@ -12,10 +12,14 @@ import cereal.messaging as messaging
import selfdrive . crash as crash
from common . basedir import BASEDIR
from common . params import Params
from common . realtime import sec_since_boot
from selfdrive . swaglog import cloudlog
from selfdrive . hardware import HARDWARE
from cereal import log
WATCHDOG_FN = " /dev/shm/wd_ "
ENABLE_WATCHDOG = os . getenv ( " NO_WATCHDOG " ) is None
def launcher ( proc ) :
try :
@ -61,6 +65,10 @@ class ManagerProcess(ABC):
enabled = True
name = " "
last_watchdog_time = 0
watchdog_max_dt = None
watchdog_seen = False
@abstractmethod
def prepare ( self ) :
pass
@ -69,6 +77,30 @@ class ManagerProcess(ABC):
def start ( self ) :
pass
def restart ( self ) :
self . stop ( )
self . start ( )
def check_watchdog ( self , started ) :
if self . watchdog_max_dt is None or self . proc is None :
return
try :
fn = WATCHDOG_FN + str ( self . proc . pid )
self . last_watchdog_time = int ( open ( fn ) . read ( ) )
except Exception :
pass
dt = sec_since_boot ( ) - self . last_watchdog_time / 1e9
if dt > self . watchdog_max_dt :
# Only restart while offroad for now
if self . watchdog_seen and ENABLE_WATCHDOG and ( not started ) :
cloudlog . error ( f " Watchdog timeout for { self . name } , restarting " )
self . restart ( )
else :
self . watchdog_seen = True
def stop ( self , retry = True ) :
if self . proc is None :
return
@ -128,7 +160,7 @@ class ManagerProcess(ABC):
class NativeProcess ( ManagerProcess ) :
def __init__ ( self , name , cwd , cmdline , enabled = True , persistent = False , driverview = False , unkillable = False , sigkill = False ) :
def __init__ ( self , name , cwd , cmdline , enabled = True , persistent = False , driverview = False , unkillable = False , sigkill = False , watchdog_max_dt = None ) :
self . name = name
self . cwd = cwd
self . cmdline = cmdline
@ -137,6 +169,7 @@ class NativeProcess(ManagerProcess):
self . driverview = driverview
self . unkillable = unkillable
self . sigkill = sigkill
self . watchdog_max_dt = watchdog_max_dt
def prepare ( self ) :
pass
@ -149,10 +182,11 @@ class NativeProcess(ManagerProcess):
cloudlog . info ( " starting process %s " % self . name )
self . proc = Process ( name = self . name , target = nativelauncher , args = ( self . cmdline , cwd ) )
self . proc . start ( )
self . watchdog_seen = False
class PythonProcess ( ManagerProcess ) :
def __init__ ( self , name , module , enabled = True , persistent = False , driverview = False , unkillable = False , sigkill = False ) :
def __init__ ( self , name , module , enabled = True , persistent = False , driverview = False , unkillable = False , sigkill = False , watchdog_max_dt = None ) :
self . name = name
self . module = module
self . enabled = enabled
@ -160,6 +194,7 @@ class PythonProcess(ManagerProcess):
self . driverview = driverview
self . unkillable = unkillable
self . sigkill = sigkill
self . watchdog_max_dt = watchdog_max_dt
def prepare ( self ) :
if self . enabled :
@ -173,6 +208,7 @@ class PythonProcess(ManagerProcess):
cloudlog . info ( " starting python %s " % self . module )
self . proc = Process ( name = self . name , target = launcher , args = ( self . module , ) )
self . proc . start ( )
self . watchdog_seen = False
class DaemonProcess ( ManagerProcess ) :
@ -234,3 +270,6 @@ def ensure_running(procs, started, driverview=False, not_run=None):
p . start ( )
else :
p . stop ( )
p . check_watchdog ( started )