From f02555949e63433a844a79a0c760bf5d4cbbe13e Mon Sep 17 00:00:00 2001 From: Calin Crisan Date: Sat, 28 Jun 2014 16:13:23 +0300 Subject: [PATCH] motion is no longer restarted upon mount error --- motioneye.py | 21 ++++++++++++++------- src/handlers.py | 27 +++++++++++++++++++++------ src/motionctl.py | 29 ++++++++++++++++++++--------- src/smbctl.py | 27 ++++++++++++++++++++------- 4 files changed, 75 insertions(+), 29 deletions(-) diff --git a/motioneye.py b/motioneye.py index 94906a2..ed6032f 100755 --- a/motioneye.py +++ b/motioneye.py @@ -279,16 +279,17 @@ def _start_motion(): import config import motionctl + ioloop = tornado.ioloop.IOLoop.instance() + # add a motion running checker def checker(): - ioloop = tornado.ioloop.IOLoop.instance() if ioloop._stopped: return - if not motionctl.running() and config.has_enabled_cameras(): + if not motionctl.running() and motionctl.started() and config.has_enabled_cameras(): try: + logging.error('motion not running, starting it') motionctl.start() - logging.info('motion started') except Exception as e: logging.error('failed to start motion: %(msg)s' % { @@ -296,7 +297,10 @@ def _start_motion(): ioloop.add_timeout(datetime.timedelta(seconds=settings.MOTION_CHECK_INTERVAL), checker) - checker() + if config.has_enabled_cameras(): + motionctl.start() + + ioloop.add_timeout(datetime.timedelta(seconds=settings.MOTION_CHECK_INTERVAL), checker) def _start_cleanup(): @@ -321,11 +325,14 @@ if __name__ == '__main__': _configure_signals() _configure_logging() - if settings.SMB_SHARES: - smbctl.update_mounts() + stop, start = smbctl.update_mounts() + if start: + _start_motion() - _start_motion() + else: + _start_motion() + _start_cleanup() if settings.THUMBNAILER_INTERVAL: diff --git a/src/handlers.py b/src/handlers.py index fea56a4..d391ee5 100644 --- a/src/handlers.py +++ b/src/handlers.py @@ -293,12 +293,19 @@ class ConfigHandler(BaseHandler): def finish(): if restart[0]: + logging.debug('motion needs to be restarted') + + motionctl.stop() + if settings.SMB_SHARES: logging.debug('updating SMB mounts') - smbctl.update_mounts() + stop, start = smbctl.update_mounts() # @UnusedVariable - logging.debug('motion needs to be restarted') - motionctl.restart() + if start: + motionctl.start() + + else: + motionctl.start() self.finish({'reload': reload, 'error': error[0]}) @@ -500,10 +507,16 @@ class ConfigHandler(BaseHandler): camera_config['@id'] = camera_id if proto == 'v4l2': + motionctl.stop() + if settings.SMB_SHARES: - smbctl.update_mounts() + stop, start = smbctl.update_mounts() # @UnusedVariable - motionctl.restart() + if start: + motionctl.start() + + else: + motionctl.start() ui_config = config.camera_dict_to_ui(camera_config) @@ -529,7 +542,9 @@ class ConfigHandler(BaseHandler): config.rem_camera(camera_id) if local: - motionctl.restart() + motionctl.stop() + if config.has_enabled_cameras(): + motionctl.start() self.finish_json() diff --git a/src/motionctl.py b/src/motionctl.py index 004e855..176a76b 100644 --- a/src/motionctl.py +++ b/src/motionctl.py @@ -16,6 +16,7 @@ # along with this program. If not, see . import errno +import logging import os.path import re import signal @@ -26,6 +27,9 @@ import config import settings +_started = False + + def find_motion(): try: binary = subprocess.check_output('which motion', shell=True).strip() @@ -46,8 +50,14 @@ def find_motion(): def start(): + global _started + + _started = True + if running(): - raise Exception('motion is already running') + return + + logging.debug('starting motion') program = find_motion() if not program: @@ -84,8 +94,14 @@ def start(): def stop(): import mjpgclient + global _started + + _started = False + if not running(): - raise Exception('motion is not running') + return + + logging.debug('stopping motion') mjpgclient.close_all() @@ -121,7 +137,6 @@ def running(): if pid is None: return False - try: os.waitpid(pid, os.WNOHANG) os.kill(pid, 0) @@ -136,12 +151,8 @@ def running(): return False -def restart(): - if running(): - stop() - - if config.has_enabled_cameras(): - start() +def started(): + return _started def _get_pid(): diff --git a/src/smbctl.py b/src/smbctl.py index 64ebcdd..43a9787 100644 --- a/src/smbctl.py +++ b/src/smbctl.py @@ -22,11 +22,12 @@ import re import subprocess import time +from tornado import ioloop + import config +import motionctl import settings -from tornado import ioloop - def find_mount_cifs(): try: @@ -127,7 +128,7 @@ def mount(server, share, username, password): except subprocess.CalledProcessError: logging.error('failed to mount smb share "//%s/%s" at "%s"' % (server, share, mount_point)) - return False + return None # test to see if mount point is writable try: @@ -139,7 +140,7 @@ def mount(server, share, username, password): except: logging.error('directory at "%s" is not writable' % mount_point) - return False + return None return mount_point @@ -157,7 +158,7 @@ def umount(server, share, username): return False try: - os.remove(mount_point) + os.rmdir(mount_point) except Exception as e: logging.error('failed to remove smb mount point "%s": %s' % (mount_point, e)) @@ -173,18 +174,25 @@ def update_mounts(): mounts = list_mounts() mounts = dict(((m['server'], m['share'], m['username'] or ''), False) for m in mounts) + should_stop = False # indicates that motion should be stopped immediately + should_start = True # indicates that motion can be started afterwards for network_share in network_shares: key = (network_share['server'], network_share['share'], network_share['username'] or '') if key in mounts: # found mounts[key] = True else: # needs to be mounted - mount(network_share['server'], network_share['share'], network_share['username'], network_share['password']) + should_stop = True + if not mount(network_share['server'], network_share['share'], network_share['username'], network_share['password']): + should_start = False # unmount the no longer necessary mounts for (network_share['server'], network_share['share'], network_share['username']), required in mounts.items(): if not required: umount(network_share['server'], network_share['share'], network_share['username']) + should_stop = True + + return (should_stop, should_start) def umount_all(): @@ -195,8 +203,13 @@ def umount_all(): def _check_mounts(): logging.debug('checking SMB mounts...') - update_mounts() + stop, start = update_mounts() + if stop: + motionctl.stop() + if start: + motionctl.start() + io_loop = ioloop.IOLoop.instance() io_loop.add_timeout(datetime.timedelta(seconds=settings.MOUNT_CHECK_INTERVAL), _check_mounts) -- 2.39.5