9

I have noticed that doing a service restart with something like:

service sshd restart

is very similar to doing something like:

pkill -HUP sshd

However the pkill would close my ssh session where the service restart would leave it open. This lead to my question and that is does a service restart send a true HUP like the pkill command? And if they do the same thing why does the service restart leave my ssh session open but the pkill closes it?

4 Answers 4

13

No. SIGHUP probably does not mean what you think it does.

In the olden days (and I'm talking 1970s here), a terminal was a device that would connect to a UNIX machine over a serial line. This was often done through a modem connection, as in those days, getting a second machine was way more expensive than having to pay for a lot of phone connectivity; and by using a modem line, you could share a machine with someone far away.

When you're done using the machine, it was quite necessary to make sure that whatever you were running would be stopped, since machines back then did not have the same amount of resources that today's machines do, and hence the system would help you ensure you did not forget to do so by sending a signal to any processes connected to your serial line when the modem would hang up. This was the 'hangup' signal, the name of which got abbreviated to SIGHUP.

At some point, someone figured out that it could sometimes make sense to have a process run continuously, so as to provide some service to the users on the machine. In order to make sure the process would indeed keep running, it was then necessary that it would be detached from the terminal on which it was started, so that when the user would disconnect and the modem would hang up, the process wouldn't be killed. Additionally, if the process would not detach from the serial line, then the terminal would not be released and the next user who tried to use it would not be able to do so. So for those reasons, you detach.

Now you have a long-running process which at some point might need to be reconfigured. You could restart it, or you could have the process poll its configuration file every so often. Both waste resources, however. It would be much better if you could tell it when to reread its configuration file. Since there's this one signal which for a daemon is meaningless anyway, why not just reuse that? Right, so that's what happened, and as z result a convention today is indeed for daemons to reread their configuration file when they receive SIGHUP.

But that's only a convention, and it is by no means a general rule. The primary and documented purpose of SIGHUP is still to signal the fact that the terminal connection has been severed. For that reason, the default action for any program upon receipt of the SIGHUP signal is still to terminate, even if the process is a daemon.

As such, an init implementation cannot just send SIGHUP to random processes that it manages. Yes, in many cases the reload action does end up sending SIGHUPto the daemon through whatever configuration the init system has (be that init scripts, systemd unit files, upstart configuration, or whatever); but it is incorrect to assume that this is what will always happen, and therefore if it's also incorrect to say that the two are equivalent.

Occasionally, this also explains why sending SIGHUP to an sshd in command of a terminal kills the session; it's because the sshd assumes something killed the connection, and that it therefore must terminate.

1
  • 3
    Very nice explanation.
    – user53029
    Commented Oct 30, 2015 at 13:27
5

From sshd(8):

 specified in the configuration file.  sshd rereads its configuration file
 when it receives a hangup signal, SIGHUP, by executing itself with the

The difference between a service script and an indiscriminate pkill -HUP sshd as root is that the service script will only target the main sshd process, while the pkill will get that process and also any child sshd processes that have been forked off that parent. Example:

% ps axo pid,ppid,command | grep ssh'[d]'
 1808     1 /usr/sbin/sshd
 8066  1808 sshd: jdoe [priv] (sshd)
28968  8066 sshd: jdoe@ttypj (sshd)
% 

init(8) (pid 1) has started the main sshd (pid 1808) and off that there's two child sshd processes for someone logged in (pids 8066 and 28968). pkill goes to all of these, while a service script would only send the HUP to pid 1808.

1

This is very service specific (so my answer ignores that you specifically mention sshd as the service)

Many services will trigger a reload when receiving a SIGHUP, but they might as well ignore the signal or terminate.

Otoh, a general service restart (and sometimes a service reload) mostly includes shutting down the server completely and starting it again (so it's often a shortcut to service $SERVICE stop; service $SERVICE start).

Finally, calling service $SERVICE reload (or any other service-command), will call a specialized script behind the scenes, that has an a priori knowledge about the service to be manipulated: so if the service in question wants a SIGHUP to reload, the script will send this signal; but it might trigger other action to the achieve the effect of reloading)

1

Assuming this is about upstart, then, no it doesn't, at least not on my system.

service is a shell script that runs initctl as you can check by viewing which service.

restart maps to stop + exec start.

stop sends SIGTERM and possibly SIGKILL if the SIGTERM hasn't worked within a reasonable period of time (least that's what the manual says).

reload is what you want if you want to send a SIGHUP to an upstart service.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .