LINUX.ORG.RU
ФорумAdmin

init.d запускает 2 процесса при тесте. при ребуте сервис не запускается

 


0

2

Что то делаю совсем не так.

По порядку:

1. этим скриптом ищется и слушается нужный порт. после того как найден:

#!/usr/bin/python
import serial
import glob
import time
import ConfigParser
import MySQLdb
import syslog

def MsgSave (Msg):
    args = [Msg,'A']
    cursor = db.cursor()
    result  = cursor.callproc('MsgSave',args)
    db.commit()
    cursor.close()
    return 1

def serial_ports():
    temp_list = glob.glob ('/dev/tty[A-Za-z]*')
    result = []
    for a_port in temp_list:
        try:
            s = serial.Serial (a_port)
            s.close ()
            result.append (a_port)
        except serial.SerialException:
            pass
    return result

def GetAquaControllerPort(RequestID,ExpectedResponce):
    AquaControllerPort = ""
    ports = serial_ports()
    for a_port in  ports:
      try:
        ser = serial.Serial()
        ser.port = a_port
        ser.baudrate = 9600
        ser.bytesize = serial.EIGHTBITS #number of bits per bytes
        ser.parity = serial.PARITY_NONE #set parity check: no parity
        ser.stopbits = serial.STOPBITS_ONE #number of stop bits
        ser.timeout = 1            #non-block read
        ser.xonxoff = False     #disable software flow control
        ser.rtscts = False     #disable hardware (RTS/CTS) flow control
        ser.dsrdtr = False       #disable hardware (DSR/DTR) flow control
        ser.writeTimeout = 2     #timeout for write
        ser.open()
#        ser.write(RequestID)
        print "RequestID to the port: " + a_port
        time.sleep(0.5)  #give the serial port sometime to receive the data

        numOfLines = 0
        while True:
          response = ser.readline()
          print("Received data: " + a_port + ":  "  + response)
          numOfLines = numOfLines + 1
          if (response.find(ExpectedResponce)>=0):
            AquaControllerPort = a_port
            print "Found AquaController port: "+a_port
            return AquaControllerPort
          if (numOfLines >= 5):
            break
        ser.close()
#        except Exception, e1:
#          print "error communicating...: " + str(e1)
      except serial.SerialException:
            pass
    return "Arduino port not found" #AquaControllerPort


#print (serial_ports())
#print GetAquaControllerPort()
#identify device later as : send request for ID - check result

ConfigFeed = ConfigParser.ConfigParser()
ConfigFeed.read('/var/aqua/aqua.ini')

db = MySQLdb.connect(user=ConfigFeed.get('DB_connection','user')
                    ,passwd=ConfigFeed.get('DB_connection','passwd')
                    ,host=ConfigFeed.get('DB_connection','host')
                    ,db=ConfigFeed.get('DB_connection','db'))
RequestID=ConfigFeed.get('SerialListener','RequestID')
ExpectedResponce=ConfigFeed.get('SerialListener','ExpectedResponce')

while 1: #try to reset connection if broken
  try:
    DevicePort =  GetAquaControllerPort(RequestID,ExpectedResponce)
    while (DevicePort.find('dev')<0):
 #     print "timeout 10 sec :"+ DevicePort
      time.sleep(10) #scan every 10 seconds until port found
      DevicePort =  GetAquaControllerPort(RequestID,ExpectedResponce)

    ser = serial.Serial(DevicePort,9600)
    syslog.syslog ('Receiving Data from ' +  DevicePort)
    while 1:
      s = ser.readline();
      #print s;
      MsgSave(s);
  except serial.SerialException, e1:
#    print "error communicating...: " + str(e1)
    syslog.syslog ('Exception from Aqua Listener: ', str(e1))
    pass

db.close
syslog.syslog('Aqua Listener stopped.')

2. Проверяю: ./aqua &

рeзультат: порт находит, слушает, делает все что нужно

3. Теперь хочу чтобы стартовал сам: в /etc/init.d file:

#!/bin/bash
### BEGIN INIT INFO
# Provides: Aqua
# Required-Start: networking
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Aqua Listener
# Description:
# pidfile: /var/run/aqua.pid
### END INIT INFO

    DAEMON_PATH="/var/aqua"
    DAEMON=aqua
#    DAEMONOPTS="-my opts"
    DAEMONOPTS=""
    NAME=aqua
    DESC="Arduino Aquarium Controller Listener"
    PIDFILE=/var/run/$NAME.pid
    SCRIPTNAME=/etc/init.d/$NAME
    case "$1" in
    start)
        printf "%-50s" "Starting $NAME..."
        cd $DAEMON_PATH
#        PID=$DAEMON  $DAEMONOPTS  > /dev/null 2>&1 & echo $!
    PID=`$DAEMON_PATH/$DAEMON $DAEMONOPTS `
#        echo "Saving PID" $PID " to " $PIDFILE
            if [ -z $PID ]; then
                printf "%s\n" "Fail"
            else
                echo $PID > $PIDFILE
                printf "%s\n" "Ok"
            fi
    ;;
    status)
            printf "%-50s" "Checking $NAME..."
            if [ -f $PIDFILE ]; then
                PID=`cat $PIDFILE`
                if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then
                    printf "%s\n" "Process dead but pidfile exists"
                else
                    echo "Running"
                fi
            else
                printf "%s\n" "Service not running"
            fi
    ;;
    stop)
            printf "%-50s" "Stopping $NAME"
                PID=`cat $PIDFILE`
                cd $DAEMON_PATH
            if [ -f $PIDFILE ]; then
                kill -HUP $PID
                printf "%s\n" "Ok"
                rm -f $PIDFILE
            else
                printf "%s\n" "pidfile not found"
            fi
    ;;
    restart)
        $0 stop
        $0 start
    ;;

    *)
            echo "Usage: $0 {status|start|stop|restart}"
            exit 1
    esac

тестируем:

sudo sh -x ./aqua start
+ DAEMON_PATH=/var/aqua
+ DAEMON=aqua
+ DAEMONOPTS=
+ NAME=aqua
+ DESC=Arduino Aquarium Controller Listener
+ PIDFILE=/var/run/aqua.pid
+ SCRIPTNAME=/etc/init.d/aqua
+ printf %-50s Starting aqua...
Starting aqua...                                  + cd /var/aqua
+ /var/aqua/aqua
процесс стартует,зависает, проверяю результат из другой сессии - работает

sudo service aqua start

Starting aqua...

проверяю результат из другой сессии: ps -a|grep aqua

10512 pts/3    00:00:00 aqua
10515 pts/3    00:00:00 aqua

4. reboot : при ребуте сервис не запускается

Питоновский код не читал, много, но:

Проверяю: ./aqua &

раз в конце строки ″&″ значит процесс сам не становится демоном, как бы не правильно. Думаю, в гугле легко находится как на питоне сделать демона (чтобы перенаправил std-потоки в /dev/null и форкнулся).

В этом случае, понятно, что строка:

PID=`$DAEMON_PATH/$DAEMON $DAEMONOPTS `

не завершится, пока выполняется процесс aqua. Либо делайте его демоном, либо лепите к нему обёртку через nohup.

reboot : при ребуте сервис не запускается

А симлинки из /etc/rc[0-6].d/ к нему сделаны? Хоть руками, хоть через chkconfig. Хотя, пока у вас не буедт нормально отрабатывать ″service aqua start″ лучше их не делать, а то система не загрузится до конца.

mky ★★★★★ ()
Ответ на: комментарий от mky

Спасибо, тест запускается по этому скрипту: http://code.activestate.com/recipes/66012-fork-a-daemon-process-on-unix/ теперь другая проблемма:
по ссылке есть тестовый код, который выводит посекундно время:

def test():
    '''
        This is an example main function run by the daemon.
        This prints a count and timestamp once per second.
    '''
    sys.stdout.write ('Message to stdout...')
    sys.stderr.write ('Message to stderr...')
    c = 0
    while 1:
        sys.stdout.write ('%d: %s\n' % (c, time.ctime(time.time())) )
        sys.stdout.flush()
        c = c + 1
        time.sleep(1)

if __name__ == "__main__":
    startstop (stdout='/var/log/aqua.log'
              ,pidfile='/var/run/aqua.pid'
              ,action=sys.argv[1])
#    main()
    test()
это работает. если переключаю на свой скрипт: main() (он в самый первый в топике, питоновский скрипт которого много) - начинаются интересные проблеммы:
сервис старт стоп статус работает
но при перезагрузке сетка теряется и мой сервис не запускается.
Сетка на WIFI через USB
Видимо опрос USB портов не проходит безнаказанно.

kapelan ()
Ответ на: комментарий от kapelan

но при перезагрузке сетка теряется и мой сервис не запускается.

Я допускаю, что ваш демон мешает запуску сети, но почему он сам не запускается? Если ему для работы нужна сеть (доступ к mysql), то его нужно ставить в загрузку попозже, чем network.

Обычно в демонах не опрашивают все порты подряд, в конфиге указывается порт и всё. А чтобы порт всегда был одним и тем же пишут udev-правило, которое создаёт симлинк на нужное устройство. Но не знаю, насколько это применимо в вашем случае.

Ну и обычно демон не делает сразу fork(), сначала он читает конфиг, пытается что-то сделать и только потом уходит в фон/освобождает терминал. Чтобы в случае явных ошибок был ненулевой код завершения и в запускающем скрипте можно было вывести FAILED.

mky ★★★★★ ()
Ответ на: комментарий от mky

Спасибо,
похоже проблемма в том что этот демон нешает сети стартовать.
Поставил везде обработку ехсепшенов, нашел что демон стартует раньше sql.
как-то так вылечилось:

def getMySQLConnection ( user,passwd,host,db):
  try:
    con = MySQLdb.connect(user=user
                        ,passwd=passwd
                        ,host=host
                        ,db=db)
  except MySQLdb.Error  as err:
    MsgLog(str(err))
  i=1
  while i==1:
    try:
      con = MySQLdb.connect(user=user
                        ,passwd=passwd
                        ,host=host
                        ,db=db)
      if con.open:
        i=2
      else:
        time.sleep(5)
    except MySQLdb.Error  as err:
      MsgLog(str(err))
  return con

kapelan ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.