Eu tenho um código C ++ que roda bem quando eu o executo a partir de um terminal Linux, mas que gera um erro EPERM quando executado a partir de um script SystemV (init.d) no bootup . O erro vem de um pthread_create com o seguinte bit de atributos atribuídos ao thread que está tentando ser criado:
pthread_t reading_thread;
pthread_attr_t read_attr;
struct sched_param read_param;
pthread_attr_init(&read_attr);
pthread_attr_setschedpolicy(&read_attr, SCHED_FIFO);
pthread_attr_setinheritsched(&read_attr, PTHREAD_EXPLICIT_SCHED);
read_param.sched_priority = 30;
pthread_attr_setschedparam(&read_attr, &read_param);
k = pthread_create(&reading_thread, &read_attr, Reading_Thread_Function,
(void*) &variable_to_pass_to_Reading_Thread_Function); // Will return EPERM
Este código funciona bem quando executado a partir do meu terminal. Ele também funciona bem no script init.d quando eu chamo "/etc/init.d/myinitdscript start". Ele também funciona bem como "sudo service myinitdscript start". O script init.d contém o seguinte:
#! /bin/sh
### BEGIN INIT INFO
# Provides: myinitdscript
# Required-Start: $local_fs $remote_fs $syslog $network
# Required-Stop: $local_fs $remote_fs $syslog $network
# Default-Start: 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts my daemon
# Description: Verbose explanation of starting my daemon
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
LOG=/home/someusershome/initd.log
NAME=myinitdscript
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
[ -x "$DAEMON" ] || (echo "$DAEMON not found. Exiting $SCRIPTNAME." >> $LOG 2>&1 && exit 0)
USERTORUNAS=a_user_on_my_system
SOURCE_SCRIPT=/home/$USERTORUNAS/source_script
DAEMON_ARGS="some_args_for_script"
. /lib/init/vars.sh
. /lib/lsb/init-functions
# Source this script for environmental variables
[ -f $SOURCE_SCRIPT ] && . $SOURCE_SCRIPT
# This is called when called with 'start', I am skipping that for succintness
do_start()
{
start-stop-daemon --start --make-pidfile --pidfile $PIDFILE --test --background --chuid $USERTORUNAS --startas /bin/bash -- -c "exec $DAEMON -- $DAEMON_ARGS >> $LOG 2>&1 " || return 1
start-stop-daemon --start --make-pidfile --pidfile $PIDFILE --background --chuid $USERTORUNAS --startas /bin/bash -- -c "exec $DAEMON -- $DAEMON_ARGS >> $LOG 2>&1" || return 2
}
Se eu ativar este script init.d usando:
update-rc.d myinitdscript defaults 99
ocorrerá erro na inicialização com um erro EPERM lançado na chamada pthread_create (k = 1, aka EPERM). Eu posso rodar isso usando o serviço mydoitdscript start do sudo, e ele rodará bem. Eu também posso chamar o /etc/init.d/myinitdscript start, e ele funcionará bem. É somente quando deixo o sistema executar este script na inicialização que ele falha.
Eu acho que se eu adicionar ao meu start-stop-daemon chama a opção "-P fifo: 99" Eu não recebo o erro EPERM e o código roda bem, exceto em uma prioridade muito alta, então eu não vou chame isso de correção. A única parte do código que precisa ser executada em tempo real é que o pthread foi criado a partir do código. Então, suponho que isso tenha a ver com minhas permissões para criar um thread em tempo real com prioridade 30 a partir de um thread normalmente agendado.
Por que meu script precisa de diretivas / prioridades de agendamento especiais quando executado da inicialização versus quando eu inicio manualmente o script init.d ou por meio de serviço?
EDIT: rodando no Ubuntu 12.04.
EDIT2: Eu tentei adicionar uma chamada para "ulimit -r" dentro do meu código que a chamada start-stop-daemon inicia, e eu fico ilimitado, então, até onde eu posso ver, não deve haver nenhum problema de permissão indo com SCHED_FIFO: 30 lá
EDIT3: Acontece que estou executando o Upstart e o Upstart possui um script de inicialização chamado rc-sysinit.conf, que inicia todos os scripts de estilo SystemV. Então talvez o Upstart esteja estragando minhas permissões.