1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

HME for Python Startup Script on Fedora Help?

Discussion in 'TiVo Home Media Features & TiVoToGo' started by jeepguy_1980, Apr 30, 2014.

  1. jeepguy_1980

    jeepguy_1980 Unregistered User

    250
    0
    Mar 1, 2008
    Newport...
    I recently upgraded (clean install) the OS on my server. It's a headless version of Fedora 19. I am having difficulty getting HME for python to start with my init.d script. This is the same script I have used before and I can't find anything that would stop it from working with Fedora 19. I am able to run pyhme manually with the following call, so it is setup properly.

    Code:
    sudo python /usr/share/pyhme/start.py
    I wrote a full wiki page, documenting how I installed pyTiVo, HME, and vidmgr. The wiki is here, if you want to see how I have everything configured.

    Below is the script I am using. Any suggestions for getting it to work would be appreciated.

    Code:
    #!/bin/bash
    # chkconfig: 2345 99 05
    # description: pyHME server
    ### INIT INFO
    # Provides: pyhme
    # Required-Start: $network
    # Required-Stop: $network
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Short-description: pyHME server
    # Description: Start and stop the pyHME server.
    ### END INIT INFO
    RETVAL=0
     
    start() {
    echo -n "Starting pyHME: "
    pgrep -f start.py
    RETVAL=$?
    [ $RETVAL -eq 0 ] && echo "pyHME already running: Exiting" && exit 1
    # this call actually starts pyHME.
    cd /usr/share/pyhme
    python start.py > /dev/null 2>&1 &
    RETVAL=$?
    [ $RETVAL -eq 0 ] && echo -n "done"
    echo
    return $RETVAL
    }
    stop() {
    echo -n "Stopping pyHME: "
    pkill -f start.py
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && echo -n "done"
    echo
    return $RETVAL
    }
    checkstatus() {
            if [ ! `pgrep -f python` ]; then
             echo -n $"pyHME is stopped"
             echo
            else
             echo "pyHME is running."
            fi
    }
    # See how we were called.
    case "$1" in
    start)
    start
    ;;
    stop)
    stop
    ;;
    status)
     checkstatus
    ;;
    
    restart|reload)
    stop
    sleep 1
    start
    RETVAL=$?
    ;;
    *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
    esac
    exit $RETVAL
     
  2. moyekj

    moyekj Well-Known Member

    11,150
    33
    Jan 23, 2006
    Mission...
    This line is throwing away potential useful stdout/stderr information:
    Code:
    python start.py > /dev/null 2>&1 &
    Replace /dev/null with a file name so you can check the file contents following a reboot to look for clues as to what may be failing.
    If that's not the failure point then add more echo lines in the script re-directing to a file that you can look at to debug and narrow in on which portion of the script is failing.
     
  3. lrhorer

    lrhorer Active Member

    6,924
    0
    Aug 31, 2003
    San...
    Moyekj is perfectly correct about you throwing away the log info.

    I'm not familiar with Fedora, but that looks like a System V init script, to me. Is Fedora now using a System V init? If so, then while I don't know if it is your problem, or not, unless my memory is quite failing me, that is not a valid init script. System V requires its init scripts to exit cleanly. That means any calls to commands inside the script must either exit and return control to the parent, or else detach from the parent and return control, which the line

    Code:
    python start.py > /dev/null 2>&1 &
    probably won't do. In short, the commands must either run and exit (like the command `ls`) or else must spawn a daemon. As you can see if look in this thread, I create a daemon script named /usr/share/pyhme/pyHME:

    Code:
    #! /bin/bash
    PIDFILE=/var/run/pyHME.pid
    RUNDIR=/usr/share/pyhme
    LOGFILE=/var/log/pyhme.log
    cd $RUNDIR
    /usr/bin/nohup /usr/bin/python2.6 $RUNDIR/start.py > $LOGFILE &
    echo $! > $PIDFILE
    exit 0
    This detaches the start.py Python script, redirects its STDOUT to a logfile, writes its PID to a file for process management, and then returns control to the parent shell. To put it simply, the script above is a daemon.

    Then in the init script, I call the daemon script per ordinary procedures for calling a daemon from an init script:

    Code:
    #! /bin/sh
    ### BEGIN INIT INFO
    # Provides:          pyHME
    # Required-Start:    $remote_fs $syslog $network $pyTivo
    # Required-Stop:     $remote_fs $syslog $network $pyTivo
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: HME Services
    # Description:       Provides HME services for TiVo
    #
    ### END INIT INFO
    
    # Author: Leslie Rhorer
    
    # Do NOT "set -e"
    
    # PATH should only include /usr/* if it runs after the mountnfs.sh script
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    DESC="HME Services"
    NAME=pyHME
    DAEMON=/usr/share/pyhme/$NAME
    DAEMON_ARGS=""
    PIDFILE=/var/run/$NAME.pid
    SCRIPTNAME=/etc/init.d/$NAME
    
    # Exit if the package is not installed
    [ -x "$DAEMON" ] || exit 0
    
    # Read configuration variable file if it is present
    [ -r /etc/default/$NAME ] && . /etc/default/$NAME
    
    # Load the VERBOSE setting and other rcS variables
    . /lib/init/vars.sh
    
    # Define LSB log_* functions.
    # Depend on lsb-base (>= 3.2-14) to ensure that this file is present
    # and status_of_proc is working.
    . /lib/lsb/init-functions
    
    #
    # Function that starts the daemon/service
    #
    do_start()
    {
    	# Return
    	#   0 if daemon has been started
    	#   1 if daemon was already running
    	#   2 if daemon could not be started
    	if [ -e "$PIDFILE" ];
    	then
    		PIDVAL=$( cat $PIDFILE )
    		ps -ef | grep $PIDVAL | grep -qv grep && return 1
    		rm $PIDFILE
    	fi
    	start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON || return 2
    }
    
    #
    # Function that stops the daemon/service
    #
    do_stop()
    {
    	# Return
    	#   0 if daemon has been stopped
    	#   1 if daemon was already stopped
    	#   2 if daemon could not be stopped
    	#   other if a failure occurred
    	if [ -e $PIDFILE ];
    	then
    		PIDVAL=$( cat $PIDFILE )
    		rm -f $PIDFILE
    		kill -15 $PIDVAL 2> /dev/null
    		return "$?"
    	else
    		return 1
    	fi
    }
    
    case "$1" in
      start)
    	[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
    	do_start
    	case "$?" in
    		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
    		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    	esac
    	;;
      stop)
    	[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
    	do_stop
    	case "$?" in
    		0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
    		2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
    	esac
    	;;
      restart)
    	#
    	# If the "reload" option is implemented then remove the
    	# 'force-reload' alias
    	#
    	log_daemon_msg "Restarting $DESC" "$NAME"
    	do_stop
    	case "$?" in
    	  0|1)
    		do_start
    		case "$?" in
    			0) log_end_msg 0 ;;
    			1) log_end_msg 1 ;; # Old process is still running
    			*) log_end_msg 1 ;; # Failed to start
    		esac
    		;;
    	  *)
    	  	# Failed to stop
    		log_end_msg 1
    		;;
    	esac
    	;;
      *)
    	echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
    	exit 3
    	;;
    esac
    This causes the init script to properly terminate, leaving the HME for Python utility running in the background:

    Code:
    RAID-Server:/usr/share/pyhme/vidmgr# ps -ef | grep python
    root       903  8128  0 01:05 pts/0    00:00:00 grep python
    root      4696     1  0 Mar08 ?        01:49:00 /usr/bin/python /usr/share/pyTivo/pyTivo.py
    root     30344     1  0 Apr25 pts/1    00:16:02 /usr/bin/python /usr/share/pyhme/start.py
    
    At any time, the admin can start, stop, or restart the HME for Python utility merely by running the init.d script with the appropriate switch.
     
  4. lrhorer

    lrhorer Active Member

    6,924
    0
    Aug 31, 2003
    San...
    Now that I have a few more minutes, I will relate what I think may be happening. The use of the ampersand (&) at the end of a command line in the various Linux shells does not detach a child process from its parent. It places the child process in the background and returns control to the parent, but the child remains a child of the parent process. Whenever the parent process terminates, its children are all sent SIGTERM signal, which normally induces them to exit. One can create an application which traps the SIGTERM signal and does something else, or the child could be hung, in either which case the child does not terminate properly, but generally when the parent exits, so do the children.

    The ampersand directive does not change this behavior. It merely allows the parent process to take over the display and start running again. Killing the parent still terminates the background process. This is one reason why calling a non-daemon routine from an init script may not be a good idea. Another reason is the init script should be kept as simple and generic as possible. It should parse the command line for proper directives (start, stop, restart, relaod, etc), make primitive calls to possibly more sophisticated daemon scripts or binaries, return the appropriate error code, and exit. This makes it easy to make changes, large or small, to the startup and / or shutdown processes without having to edit the init scripts at all. It also allows one to do all sorts of housekeeping, whether elegant or ugly, during the initialization or shutdown.

    If the binary being called by the startup script (in this case Python) does not either detach itself from the parent process or run and terminate, then the nohup command will tell the OS to detach the child from the parent, attaching the child to the init process (PID 1). Some Linux shells have a built-in nohup command, but in the absence of a built-in command, the nohup utility is readily available for all Linux distributions. Most include nohup in the base distro.
     
  5. jeepguy_1980

    jeepguy_1980 Unregistered User

    250
    0
    Mar 1, 2008
    Newport...
    Thanks for the detailed response. I haven't had much time to fix this. But I want to try fixing it this weekend.

    The script you posted doesn't work for me. It doesn't like

    Code:
    . /lib/init/vars.sh
    I believe that fedora went away from SysV. Below is the script I use for pytivo, which does work. It's nearly identical to the pyhme script, except it works.

    Code:
    !/bin/bash
    # chkconfig: 2345 99 05
    # description: pyTivo server
    
    ### INIT INFO
    # Provides: pytivo
    # Required-Start: $network
    # Required-Stop: $network
    # Default-Start: 2 3 4 5
    # Default-Stop: 0 1 6
    # Short-description: pyTivo server
    # Description: Start and stop the pyTivo server.
    ### END INIT INFO
    
    RETVAL=0
    
    
    start() {
    echo -n "Starting pyTivo: "
    pgrep -f pyTivo.py
    RETVAL=$?
    [ $RETVAL -eq 0 ] && echo "pyTivo already running: Exiting" && exit 1
    
    # this call actually starts pyTivo.
    python /usr/share/pytivo/pyTivo.py > /dev/null 2>&1 &
    RETVAL=$?
    [ $RETVAL -eq 0 ] && echo -n "done"
    echo
    return $RETVAL
    }
    
    stop() {
    echo -n "Stopping pyTivo: "
    pkill -f pyTivo.py
    RETVAL=$?
    echo
    [ $RETVAL -eq 0 ] && echo -n "done"
    echo
    return $RETVAL
    }
    
    # See how we were called.
    case "$1" in
    start)
    start
    ;;
    stop)
    stop
    ;;
    restart|reload)
    stop
    sleep 1
    start
    RETVAL=$?
    ;;
    *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
    esac
    exit $RETVAL
     

Share This Page