1) If the daemon uses a lock file, the file is usually stored in /var/run. And the name of file is usually name.pid, where name is the name of the daemon or the service.
ubuntu@ip-172-31-23-227:~$ ls -lrt /var/run/*.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/upstart-udev-bridge.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/dhclient.eth0.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/upstart-socket-bridge.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/rsyslogd.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/upstart-file-bridge.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/acpid.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/sshd.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/crond.pid
-rw-r--r-- 1 root root 4 Oct 11 20:56 /var/run/atd.pid
2) If the daemon supports configuration options, they are usually stored in /etc. The configuration file is named name.conf
ubuntu@ip-172-31-23-227:~$ ls -lrt /etc/*.conf
-rw-r--r-- 1 root root 2584 Oct 10 2012 /etc/gai.conf
-rw-r--r-- 1 root root 2084 Apr 1 2013 /etc/sysctl.conf
-rw-r--r-- 1 root root 1245 Apr 18 2013 /etc/rsyslog.conf
-rw-r--r-- 1 root root 771 May 18 2013 /etc/insserv.conf
-rw-r----- 1 root fuse 280 May 24 2013 /etc/fuse.conf
......
3) the daemon process can be started from the command line, but they are usually started from one of the system initialization scripts .
4) If the daemon has a configuration file, the daemon reads it when it starts, but usually won't look at it again. If the admin want to change the config, he/she needs to restart the daemon.
2. Re-read config file example:
daemon.c:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<syslog.h>
#include<errno.h>
#include<string.h>
#include<pthread.h>
#include<signal.h>
sigset_t mask;
int already_running(void)
{
// Code to lock the file and detect if the daemon process
// is already running
// ......
return 0;
}
void reread()
{
// Code to reread configuration file
}
void * thr_fn(void *arg)
{
int err, signo;
for(;;) {
// wait for signal coming
err = sigwait(&mask, &signo);
if(err != 0) {
syslog(LOG_ERR, "sigwait failed");
exit(1);
}
// Process signals
switch(signo) {
case SIGHUP:
printf("Re-reading configuration file");
reread();
break;
case SIGTERM:
printf("got SIGTERM, exiting");
exit(0);
default:
syslog(LOG_INFO, "unexpected signal %d\n", signo);
}
}
return(0);
}
void daemonize()
{
// code to make the process to become a daemon
// ......
}
int main(int argc, char* argv[])
{
int err;
pthread_t tid;
struct sigaction sa;
// Become a daemon
daemonize();
// Make sure only one daemon is running
if(already_running()) {
syslog(LOG_ERR, "daemon already running!");
exit(1);
}
// Restore SIGHUP default and block all signals
sa.sa_handler = SIG_DFL;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if(sigaction(SIGHUP, &sa, NULL) < 0) {
printf("sigaction error!\n");
exit(2);
}
// block all signals for main thread, so the newly created thread
// is responsible for handling signals
sigfillset(&mask);
if((err = pthread_sigmask(SIG_BLOCK, &mask, NULL)) != 0) {
printf("pthread_sigmask error!\n");
exit(3);
}
// Create a thread to handle SIGHUP AND SIGTERM
err = pthread_create(&tid, NULL, thr_fn, 0);
if(err != 0) {
printf("pthread_create error!\n");
exit(4);
}
sleep(5);
exit(0);
}
shell:
The program launches a separate thread to help handle signals and re-read configuration if SIGHUP comes.
ubuntu@ip-172-31-23-227:~$ kill -1 30893
ubuntu@ip-172-31-23-227:~$ Re-reading configuration file
[1]+ Done ./daemon.out
ubuntu@ip-172-31-23-227:~$ ./daemon.out &
[1] 30895
ubuntu@ip-172-31-23-227:~$ kill -15 30895
ubuntu@ip-172-31-23-227:~$ got SIGTERM, exiting
[1]+ Done ./daemon.out
3. Re-read config without using multithreading
daemon.c:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<syslog.h>
#include<errno.h>
#include<string.h>
#include<signal.h>
sigset_t mask;
int already_running(void)
{
// Code to lock the file and detect if the daemon process
// is already running
// ......
return 0;
}
void reread()
{
// Code to reread configuration file
}
void daemonize()
{
// code to make the process to become a daemon
// ......
}
void sigterm(int signo)
{
printf("got SIGTERM: exiting");
exit(0);
}
void sighup(int signo)
{
printf("got SIGHUP: re-read config file");
reread();
}
int main(int argc, char* argv[])
{
int err;
struct sigaction sa;
// Become a daemon
daemonize();
// Make sure only one daemon is running
if(already_running()) {
syslog(LOG_ERR, "daemon already running!");
exit(1);
}
// Handle signals
sa.sa_handler = sigterm;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGHUP);
sa.sa_flags = 0;
if(sigaction(SIGTERM, &sa, NULL) < 0) {
printf("sigaction error!\n");
exit(2);
}
sa.sa_handler = sighup;
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGTERM);
sa.sa_flags = 0;
if(sigaction(SIGHUP, &sa, NULL) < 0) {
printf("sigaction error!\n");
exit(2);
}
sleep(5);
exit(0);
}
shell:
ubuntu@ip-172-31-23-227:~$ kill -1 31808
ubuntu@ip-172-31-23-227:~$ got SIGHUP: re-read config file
[1]+ Done ./daemon.out
ubuntu@ip-172-31-23-227:~$ ./daemon.out &
[1] 31809
ubuntu@ip-172-31-23-227:~$ kill -15 31809
ubuntu@ip-172-31-23-227:~$ got SIGTERM: exiting
[1]+ Done ./daemon.out
No comments:
Post a Comment