2

My earlier problem revealed that reloading the config of my Debian GNU/Linux 6.0 nginx reverse proxy does not work, while restarting, or reloading directly through the binary does work.

I have looked into the /etc/init.d/nginx file to see what exactly might go wrong there but since this is written by Sergey Budnevitch from nginx i didn't dare to fiddle with it.

The contents of my probably old version of the file:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $network $remote_fs $local_fs
# Required-Stop:     $network $remote_fs $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Stop/start nginx
### END INIT INFO

# Author: Sergey Budnevitch <sb@nginx.com>

PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC=nginx
NAME=nginx
CONFFILE=/etc/nginx/nginx.conf
DAEMON=/usr/sbin/nginx
DAEMON_ARGS="-c $CONFFILE"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

[ -x $DAEMON ] || exit 0

[ -r /etc/default/$NAME ] && . /etc/default/$NAME

. /lib/init/vars.sh

. /lib/lsb/init-functions

do_start()
{
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \
        $DAEMON_ARGS
    RETVAL="$?"
    return "$RETVAL"
}

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
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    rm -f $PIDFILE
    return "$RETVAL"
}

do_reload() {
    #
    start-stop-daemon --stop --signal HUP --quiet --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    return "$RETVAL"
}

do_configtest() {
    if [ "$#" -ne 0 ]; then
        case "$1" in
            -q)
                FLAG=$1
                ;;
            *)
                ;;
        esac
        shift
    fi
    $DAEMON -t $FLAG -c $CONFFILE
    RETVAL="$?"
    return $RETVAL
}

do_upgrade() {
    OLDBINPIDFILE=$PIDFILE.oldbin

    do_configtest -q || return 6
    start-stop-daemon --stop --signal USR2 --quiet --pidfile $PIDFILE --name $NAME
    RETVAL="$?"
    sleep 1
    if [ -f $OLDBINPIDFILE -a -f $PIDFILE ]; then
        start-stop-daemon --stop --signal QUIT --quiet --pidfile $OLDBINPIDFILE --name $NAME
        RETVAL="$?"
    else
        echo $"Upgrade failed!"
        RETVAL=1
        return $RETVAL
    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
        ;;
  status)
        status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
        ;;
  configtest)
        do_configtest
        ;;
  upgrade)
        do_upgrade
        ;;
  reload|force-reload)
        log_daemon_msg "Reloading $DESC" "$NAME"
        do_reload
        log_end_msg $?
        ;;
  restart|force-reload)
        log_daemon_msg "Restarting $DESC" "$NAME"
        do_configtest -q || exit $RETVAL
        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|status|restart|reload|force-reload|upgrade|configtest}" >&2
        exit 3
        ;;
esac

exit $RETVAL

I also couldn't find the log file log_daemon_msg writes to.

This is where i don't know what else to do; Google as well as this sites "Questions that may already have your answer"-suggestions only find answers to questions asking for the reload feature.

logicBV
  • 33
  • 1
  • 2
  • 5
  • What OS you are using and what is the path of your NGINX binary ? – Abhishek Anand Amralkar Sep 04 '14 at 15:09
  • OS is Debian GNU/Linux 6.0, nginx binary is at /usr/sbin/nginx, the init.d/nginx has it right with DAEMON=/usr/sbin/nginx – logicBV Sep 05 '14 at 06:36
  • Try `kill -HUP $(cat /var/run/nginx.pid)` and `nginx -s reload` while observing nginx' error log. If the latter works (`[notice] *****: signal process started`) but the former doesn't, then the problem is not in the init script, but in the HUP signal either not getting delivered or not getting processed by nginx. I have the same issue on a Ubuntu 12.04 with nginx 1.4.7 – Nils Toedtmann Sep 05 '14 at 08:19
  • Does /etc/default/nginx exists? – thanasisk Sep 05 '14 at 08:20
  • @Nils Toedtmann: You are right, i had already oberserved `nginx -s reload` generating a notice while `/etc/init.d/nginx reload` didn't but couldn't make any sense of it. `kill -HUP \`cat /var/run/nginx.pid\`` also doesn't generate the notice so it must be what you said. Could you elaborate on `the HUP signal either not getting delivered or not getting processed by nginx`, what can be done? – logicBV Sep 05 '14 at 09:42
  • @thanasisk: Yes it does, but nothing impactful happens there: `DAEMON_OPTS=""` – logicBV Sep 05 '14 at 09:44
  • (Note: i just realize that the notice "signal process started" triggered by `nginx -s reload` might not mean much, config might still not get reloaded) -- According to http://wiki.nginx.org/CommandLine the HUP signal should make nginx reload its conf. So if nginx doesn't do that, then either it never received the signal sent with `kill -HUP $PID` (maybe some too strict SElinux/apparmor rule?), or it's behaving not as documented. – Nils Toedtmann Sep 05 '14 at 10:07
  • I tested a bit and found that my nginx *does* successfully reload with any of the above commands, it only doesn't mention this fact in any of its logs. -- I suggest you double check that nginx really isn't reloading its config. If it really doesn't, then check for security frameworks like SElinux, AppArmour etc whether they filter the HUP signal – Nils Toedtmann Sep 05 '14 at 10:18
  • Well now i feel like a complete idiot. I checked again and /etc/init.d/nginx reload **does** work. So it just didn't before i last restarted (which i had to do just because reload did nothing). This probably also means all of the three reload variants didn't work before the restart, as every one of them works now after the restart. I'm not going to persue now what caused reload functionality to cease. Do you want to write an answer telling people to doublecheck stuff after a restart which i can accept - or how do you deal with those kind of questions here? Sorry for wasting everyones' time. – logicBV Sep 05 '14 at 12:19

1 Answers1

1

(I am aware that this is not a full answer, only advise how to troubleshoot. But it helped at least in this case)

Double and triple check that nginx is really not reloading, even after a restart (nginx might be stuck in an unhealthy state). It is easy to wrongly think nginx would not reload.

Here is how you can verify:

Note that in many default configurations, nginx is - other than Apache - not mentioning a reload in its logs! E.g. on my Ubuntus, I only get a reaction in the logs if i increase the error_log level to 'debug'. Therefore i recommend to apply some small and unambiguous change to your config every time you reload. E.g. add

add_header X-config-version 0001;

and increment it before each reload. You can then check witch config nginx is using via

curl -s -I $URL | grep X-config-version

Also, verify the config syntax before each reload attempt (yes, nginx should give you a proper error message when attempting to reload a bad config. But still, you want to exclude this possible cause):

$PATH_TO/nginx  -t

Now test reload. To be sure, avoid the scripts provided by the OS (/etc/init.d/nginx, service/invoke-rc.d/reload, ...) and try the two official methods:

$PATH_TO/nginx  -s reload

and/or

kill  -HUP  $PID_OF_NGINX_MASTER_PROCESS

e.g.

kill  -HUP  `cat /var/run/nginx.pid`

If you have proven that nginx is really restarting but not reloading, then ... ping me and i'll try to help you troubleshooting :-)

Nils Toedtmann
  • 3,342
  • 5
  • 26
  • 36