110 lines
3.6 KiB
Python
Executable File
110 lines
3.6 KiB
Python
Executable File
#!/usr/bin/python3
|
|
|
|
# Copyright (C) 2009 Canonical Ltd.
|
|
# Author: Andy Whitcroft <apw@ubuntu.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by the
|
|
# Free Software Foundation; either version 2 of the License, or (at your
|
|
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
|
|
# the full text of the license.
|
|
|
|
"""Detect and report suspend/hibernate/resume failures.
|
|
|
|
If a suspend/hibernate is marked as still in progress during a normal
|
|
system boot we know that that operation has failed. Use that to
|
|
generate an apport bug report.
|
|
"""
|
|
|
|
import datetime
|
|
import os
|
|
import sys
|
|
from gettext import gettext as _
|
|
|
|
import apport.report
|
|
from apport.hookutils import attach_file_if_exists
|
|
from apport.packaging_impl import impl as packaging
|
|
|
|
|
|
# pylint: disable-next=missing-function-docstring
|
|
def main(argv=None):
|
|
if argv is None:
|
|
argv = sys.argv
|
|
|
|
try:
|
|
if not packaging.enabled():
|
|
return -1
|
|
|
|
report = apport.report.Report(problem_type="KernelOops")
|
|
|
|
libdir = "/var/lib/pm-utils"
|
|
flagfile = f"{libdir}/status"
|
|
stresslog = f"{libdir}/stress.log"
|
|
hanglog = f"{libdir}/resume-hang.log"
|
|
|
|
report.add_os_info()
|
|
report.add_proc_info()
|
|
report.add_user_info()
|
|
report.add_package(apport.packaging.get_kernel_package())
|
|
|
|
# grab the contents of the suspend/resume flag file
|
|
attach_file_if_exists(report, flagfile, "Failure")
|
|
|
|
# grab the contents of the suspend/hibernate log file
|
|
attach_file_if_exists(report, "/var/log/pm-suspend.log", "SleepLog")
|
|
|
|
# grab the contents of the suspend/resume stress test log if present.
|
|
attach_file_if_exists(report, stresslog, "StressLog")
|
|
|
|
# Ensure we are appropriately tagged.
|
|
if "Failure" in report:
|
|
report.add_tags(["resume ", report["Failure"]])
|
|
|
|
# Record the failure mode.
|
|
report["Failure"] += "/resume"
|
|
|
|
# If we had a late hang pull in the resume-hang logfile. Also
|
|
# add an additional tag so we can pick these out.
|
|
if os.path.exists(hanglog):
|
|
attach_file_if_exists(report, hanglog, "ResumeHangLog")
|
|
report.add_tags(["resume-late-hang"])
|
|
|
|
# Generate a sensible report message.
|
|
if report.get("Failure") == "suspend/resume":
|
|
report["Annotation"] = _(
|
|
"This occurred during a previous suspend,"
|
|
" and prevented the system from resuming properly."
|
|
)
|
|
else:
|
|
report["Annotation"] = _(
|
|
"This occurred during a previous hibernation,"
|
|
" and prevented the system from resuming properly."
|
|
)
|
|
|
|
# If we had a late hang make sure the dialog is clear that they may
|
|
# not have noticed. Also update the bug title so we notice.
|
|
if os.path.exists(hanglog):
|
|
report["Annotation"] += " " + _(
|
|
"The resume processing hung very near the end"
|
|
" and will have appeared to have completed normally."
|
|
)
|
|
report["Failure"] = "late resume"
|
|
|
|
if report.check_ignored():
|
|
return 0
|
|
|
|
nowtime = datetime.datetime.now()
|
|
pr_filename = f"/var/crash/susres.{str(nowtime).replace(' ', '_')}.crash"
|
|
with os.fdopen(
|
|
os.open(pr_filename, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o640), "wb"
|
|
) as report_file:
|
|
report.write(report_file)
|
|
return 0
|
|
except Exception:
|
|
print("apportcheckresume failed")
|
|
raise
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|