diff --git a/scripts/determine-reboot-cause b/scripts/determine-reboot-cause index a0ddc21a..b5c4a85a 100755 --- a/scripts/determine-reboot-cause +++ b/scripts/determine-reboot-cause @@ -29,6 +29,8 @@ REBOOT_CAUSE_FILE = os.path.join(REBOOT_CAUSE_DIR, "reboot-cause.txt") PREVIOUS_REBOOT_CAUSE_FILE = os.path.join(REBOOT_CAUSE_DIR, "previous-reboot-cause.json") FIRST_BOOT_PLATFORM_FILE = "/tmp/notify_firstboot_to_platform" REBOOT_TYPE_KEXEC_FILE = "/proc/cmdline" +TMP_DIR="/tmp" +REBOOT_PROCESSED_FILE = os.path.join(TMP_DIR, "previous-reboot-cause-processed") # The following SONIC_BOOT_TYPEs come from the warm/fast reboot script which is in sonic-utilities # Because the system can be rebooted from some old versions, we have to take all possible BOOT options into consideration. # On 201803, 201807 we have @@ -218,6 +220,10 @@ def main(): sonic_logger.log_error("User {} does not have permission to execute".format(pwd.getpwuid(os.getuid()).pw_name)) sys.exit("This utility must be run as root") + if os.path.exists(REBOOT_PROCESSED_FILE): + sonic_logger.log_info("User {} : reboot-cause already processed. Nothing to do. Exiting...".format(pwd.getpwuid(os.getuid()).pw_name)) + return + # Create REBOOT_CAUSE_DIR if it doesn't exist if not os.path.exists(REBOOT_CAUSE_DIR): os.makedirs(REBOOT_CAUSE_DIR) @@ -257,6 +263,10 @@ def main(): with open(REBOOT_CAUSE_FILE, "w") as cause_file: cause_file.write(REBOOT_CAUSE_UNKNOWN) + # Create tmp reboot processed file to mark processing of last reboot cause during current boot. + # This is used to prevent reprocessing of reboot cause if this service restarts. + with open(REBOOT_PROCESSED_FILE, "w") as reboot_processed_file: + reboot_processed_file.write("processed last reboot cause") if __name__ == "__main__": main() diff --git a/tests/determine-reboot-cause_test.py b/tests/determine-reboot-cause_test.py index 6bf52fe5..6140ffcf 100644 --- a/tests/determine-reboot-cause_test.py +++ b/tests/determine-reboot-cause_test.py @@ -71,7 +71,8 @@ EXPECTED_KERNEL_PANIC_REBOOT_CAUSE_DICT = {'comment': '', 'gen_time': '2021_3_28_13_48_49', 'cause': 'Kernel Panic', 'user': 'N/A', 'time': 'Sun Mar 28 13:45:12 UTC 2021'} REBOOT_CAUSE_DIR="host/reboot-cause/" - +TMP_DIR="tmp/" +REBOOT_PROCESSED_FILE="tmp/previous-reboot-cause-processed" class TestDetermineRebootCause(object): def test_parse_warmfast_reboot_from_proc_cmdline(self): with mock.patch("os.path.isfile") as mock_isfile: @@ -179,23 +180,58 @@ def test_determine_reboot_cause_software_hardware(self): assert additional_info == EXPECTED_FIND_SOFTWARE_REBOOT_CAUSE_USER @mock.patch('determine_reboot_cause.REBOOT_CAUSE_DIR', os.path.join(os.getcwd(), REBOOT_CAUSE_DIR)) + @mock.patch('determine_reboot_cause.TMP_DIR', os.path.join(os.getcwd(), TMP_DIR)) @mock.patch('determine_reboot_cause.REBOOT_CAUSE_HISTORY_DIR', os.path.join(os.getcwd(), 'host/reboot-cause/history/')) @mock.patch('determine_reboot_cause.PREVIOUS_REBOOT_CAUSE_FILE', os.path.join(os.getcwd(), 'host/reboot-cause/previous-reboot-cause.json')) @mock.patch('determine_reboot_cause.REBOOT_CAUSE_FILE', os.path.join(os.getcwd(),'host/reboot-cause/reboot-cause.txt')) + @mock.patch('determine_reboot_cause.REBOOT_PROCESSED_FILE', os.path.join(os.getcwd(),'tmp/previous-reboot-cause-processed')) def test_determine_reboot_cause_main_without_reboot_cause_dir(self): if os.path.exists(REBOOT_CAUSE_DIR): shutil.rmtree(REBOOT_CAUSE_DIR) + if not os.path.exists(TMP_DIR): + os.makedirs(TMP_DIR) + if os.path.exists(REBOOT_PROCESSED_FILE): + os.remove(REBOOT_PROCESSED_FILE) with mock.patch("os.geteuid", return_value=0): determine_reboot_cause.main() assert os.path.exists("host/reboot-cause/reboot-cause.txt") == True assert os.path.exists("host/reboot-cause/previous-reboot-cause.json") == True + assert os.path.exists(REBOOT_PROCESSED_FILE) == True @mock.patch('determine_reboot_cause.REBOOT_CAUSE_DIR', os.path.join(os.getcwd(), REBOOT_CAUSE_DIR)) + @mock.patch('determine_reboot_cause.TMP_DIR', os.path.join(os.getcwd(), TMP_DIR)) @mock.patch('determine_reboot_cause.REBOOT_CAUSE_HISTORY_DIR', os.path.join(os.getcwd(), 'host/reboot-cause/history/')) @mock.patch('determine_reboot_cause.PREVIOUS_REBOOT_CAUSE_FILE', os.path.join(os.getcwd(), 'host/reboot-cause/previous-reboot-cause.json')) @mock.patch('determine_reboot_cause.REBOOT_CAUSE_FILE', os.path.join(os.getcwd(),'host/reboot-cause/reboot-cause.txt')) + @mock.patch('determine_reboot_cause.REBOOT_PROCESSED_FILE', os.path.join(os.getcwd(),'tmp/previous-reboot-cause-processed')) def test_determine_reboot_cause_main_with_reboot_cause_dir(self): + if not os.path.exists(TMP_DIR): + os.makedirs(TMP_DIR) + if os.path.exists(REBOOT_PROCESSED_FILE): + os.remove(REBOOT_PROCESSED_FILE) with mock.patch("os.geteuid", return_value=0): determine_reboot_cause.main() assert os.path.exists("host/reboot-cause/reboot-cause.txt") == True assert os.path.exists("host/reboot-cause/previous-reboot-cause.json") == True + assert os.path.exists(REBOOT_PROCESSED_FILE) == True + + @mock.patch('determine_reboot_cause.REBOOT_CAUSE_DIR', os.path.join(os.getcwd(), REBOOT_CAUSE_DIR)) + @mock.patch('determine_reboot_cause.TMP_DIR', os.path.join(os.getcwd(), TMP_DIR)) + @mock.patch('determine_reboot_cause.REBOOT_CAUSE_HISTORY_DIR', os.path.join(os.getcwd(), 'host/reboot-cause/history/')) + @mock.patch('determine_reboot_cause.PREVIOUS_REBOOT_CAUSE_FILE', os.path.join(os.getcwd(), 'host/reboot-cause/previous-reboot-cause.json')) + @mock.patch('determine_reboot_cause.REBOOT_CAUSE_FILE', os.path.join(os.getcwd(),'host/reboot-cause/reboot-cause.txt')) + @mock.patch('determine_reboot_cause.REBOOT_PROCESSED_FILE', os.path.join(os.getcwd(),'tmp/previous-reboot-cause-processed')) + def test_determine_reboot_cause_test_restart(self): + if os.path.exists(REBOOT_CAUSE_DIR): + shutil.rmtree(REBOOT_CAUSE_DIR) + if not os.path.exists(TMP_DIR): + os.makedirs(TMP_DIR) + if not os.path.exists(REBOOT_PROCESSED_FILE): + os.mknod(REBOOT_PROCESSED_FILE) + with mock.patch("os.geteuid", return_value=0): + determine_reboot_cause.main() + assert os.path.exists("host/reboot-cause/reboot-cause.txt") == False + assert os.path.exists("host/reboot-cause/previous-reboot-cause.json") == False + assert os.path.exists(REBOOT_PROCESSED_FILE) == True + if os.path.exists(TMP_DIR): + shutil.rmtree(TMP_DIR)