Daemon Processes - Tamkang University

Download Report

Transcript Daemon Processes - Tamkang University

Daemon Processes
Computer Network Programming
1
Motivation
• You wrote a server and you want to have it running
all the time so that clients can connect and use your
service at any time.
– Examples: Web serves, telnet servers, ftp servers, domain
name servers, etc.
• You don’t want your server to be killed when you
logout or when you press ^C.
• You want your server to be running in the
background silently without disturbing others and
without getting disturbed by others.
• You want to run it for a long-time: for days, months,
years maybe.
• You want it to be started automatically when the
system boots up.
2
Daemon Processes
• Solution: You need to run your server as a
daemon!
• A daemon is a process that runs in the
background and is independent of control
from all terminals.
• A daemon process usually performs server tasks and
administrative tasks
• There are 20-50 daemon processes running in a
Unix system: silently.
3
Some daemons running on a Unix system
root 139 1 0 Mar 22 ?
root 144 1 0 Mar 22 ?
root 161 1 0 Mar 22 ?
root 146 1 0 Mar 22 ?
root 227 1 0 Mar 22 ?
root 165 1 0 Mar 22 ?
root 179 1 0 Mar 22 ?
root 303 1 0 Mar 22 ?
root 295 1 0 Mar 22 ?
root 297 1 0 Mar 22 ?
root 313 1 0 Mar 22 ?
root 16223 1 0 Mar 26 ?
root 312 1 0 Mar 22 ?
root 284 1 0 Mar 22 ?
root 19274 139 0 Mar 27 ?
root 15160 1 0 Mar 26 ?
root 791 139 0 Mar 23 ?
root 24477 139 0 14:10:32 ?
……….
truncated output
0:07 /usr/sbin/inetd -s
0:01 /usr/lib/nfs/statd
1:49 /usr/lib/autofs/automountd
0:00 /usr/lib/nfs/lockd
0:07 /usr/lib/utmpd
0:22 /usr/sbin/syslogd -n -z 18
0:02 /usr/sbin/cron
0:01 /usr/lib/snmp/snmpdx -y -c /etc/snmp/conf
0:03 /usr/lib/nfs/mountd
0:00 /usr/lib/nfs/nfsd -a 16
0:00 /usr/lib/dmi/snmpXdmid -s aspendos
1:00 /usr/lib/lpsched
0:00 /usr/lib/dmi/dmispd
0:08 /usr/dt/bin/dtlogin -daemon
0:00 in.rlogind
0:00 /aspendosh/apache/bin/httpd
0:18 /usr/dt/bin/rpc.ttdbserverd
0:00 in.telnetd
4
Why independence from all
terminals
• Assume you start your daemon from a
terminal (xterm, dump terminal, etc).
– You want to use the same terminal for other
tasks. Hence you don’t want the daemon to
print out messages to the screen while you are
doing some other tasks
– When the user presses interrupt keys (^C), you
don’t want your daemon to be killed.
5
How to start a daemon
– Start it from a system initialization script during
system startup.
– inetd, syslogd, sendmail, httpd are
examples
– inetd starts the daemon (service)
– ftpd, telnetd, etc. are started from the inetd process.
– cron daemon starts them at regular intervals
– at command can be used to execute a server at
a well-specified time in the future.
– Can be started from user terminal:
» to test the daemon
» to restart a died daemon
6
syslogd daemon
• Used to log messages (error messages, information
messages, all kinds of messages)
• Daemons usually don’t print messages on the
screen. They send the messages to the syslogd and it
logs everything or prints to console if necessary
7
Uses select() to multiplex input from multiple sources
- input from UDP socket (port 514)
- input from Unix domain socket (/var/run/log)
- input from Kernel (/dev/klog device)
- output to log file(s)
- output to console
- output to user
- output to an other
syslogd
console
Log file
Daemon
Daemon
Udp Socket
Process
Unix Domain
Socket
Daemon
Syslogs reads a configuration
file /etc/syslog.conf
to learn what to do with each kind
of message
syslogd
Process
/dev/klog
kernel
Messages
8
syslog() function
• A daemon does not have a controlling terminal
(a keyboard/screen for example), hence it can not call printf..
• It calls syslog() function to output a error messages or log
messages to the syslogd and syslogd stores the message or
writes it to the console. Syslog() function sends the message
to the syslogd.
void syslog(int priority, const
char* message, ….);
priority is combination of level and facility flags.
message is a format string like printf().
then some arguments may follow
9
Level denotes the severity of the message:
crital, error, info, debug message etc.
Facility identifies the type of the process sending the message
ftp daemon, kernel, mail system, a user process, local
use, etc.
Example:
syslog (LOG_INFO | LOG_LOCAL2, “rename error: %s %s”,
file1, file2)
syslogd uses the configuration file /etc/syslog.conf and level and facility
parameters to decide what to do with each incoming message.
/etc/syslogd.conf file content
*.err;kern.notice;auth.notice
*.err;kern.debug;daemon.notice;mail.crit
/dev/console
/var/adm/message
10
Use of syslog() function
static void
err_doit(int errnoflag, int level, const char *fmt, va_list ap)
{
int
errno_save, n;
char buf[MAXLINE];
errno_save = errno;
vsprintf(buf, fmt, ap); n = strlen(buf);
if (errnoflag)
snprintf(buf+n, sizeof(buf)-n, ": %s", strerror(errno_save));
strcat(buf, "\n");
if (daemon_proc) {
syslog (level, buf); /* send to syslogd daemon for logging */
} else {
fflush(stdout);
/* print out to the screen */
fputs(buf, stdout);
fflush(stdout);
}
return;
}
11
How can we daemonize a process
#define MAXFD 64
extern int
daemon_proc; /* defined in error.c */
void daemon_init(const char *pname, int facility)
{
int
i;
pid_t
pid;
if ( (pid = Fork()) != 0)
exit(0);
/* parent terminates */
/* 1st child continues */
setsid();
/* become session leader */
Signal(SIGHUP, SIG_IGN);
if ( (pid = Fork()) != 0)
exit(0);
/* 1st child terminates */
/* 2nd child continues */
daemon_proc = 1;
/* for our err_XXX() functions */
chdir("/");
/* change working directory */
umask(0);
/* clear our file mode creation mask */
for (i = 0; i < MAXFD; i++)
close(i);
openlog(pname, LOG_PID, facility);
}
12
A daemon process will never receive the following signals
from the kernel: SIG_HUP, SIG_INT, SIH_WINCH.
Usually SIG_HUP signal is given to the daemon by system
administrators to make the daemon reread its confıguration
file(s).
Exampe: kill -HUP inetd
13
Daytime tcp server as a daemon
int main(int argc, char **argv)
{
int listenfd, connfd; socklen_t addrlen, len;
struct sockaddr *cliaddr; char buff[MAXLINE];
time_t ticks;
daemon_init(argv[0], 0);
if (argc == 2)
listenfd = Tcp_listen(NULL, argv[1], &addrlen);
else if (argc == 3)
listenfd = Tcp_listen(argv[1], argv[2], &addrlen);
else
err_quit("usage: daytimetcpsrv2 [ <host> ] <service or port>");
cliaddr = Malloc(addrlen);
for ( ; ; ) {
len = addrlen;
connfd = Accept(listenfd, cliaddr, &len);
err_msg("connection from %s", Sock_ntop(cliaddr, len));
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
Write(connfd, buff, strlen(buff));
Close(connfd);
}
}
14
inetd daemon
internet superserver
There are a lot of internet servers that will be running on a
typical Unix system
- FTP, telnet, rlogin, TFTP, daytime, time, echo Servers
In earlier systems, each service had a process (daemon)
associated with.
- each process does the same startup tasks
creating sockets, binding listening….
- each process took an entry in the process table
- these processes are asleep most of the time waiting for requests.
After 4.3 BSD Unix system, a single server inetd daemon is used to wait for
requests for all of these services and then create the corresponding server
process on demand.
15
/etc/inetd.conf file
ftp
telnet
name
shell
login
tftp
stream
stream
dgram
stream
stream
dgram
tcp
tcp
udp
tcp
tcp
udp
nowait
nowait
wait
nowait
nowait
wait
root
root
root
root
root
root
/usr/sbin/in.ftpd
/usr/sbin/in.telnetd
/usr/sbin/in.tnamed
/usr/sbin/in.rshd
/usr/sbin/in.rlogind
/usr/sbin/in.tftpd
in.ftpd
in.telnetd
in.tnamed
in.rshd
in.rlogind
in.tftpd -s /tftpboot
reads the configuration file upon startup
inetd
Has a listening socket for each
TCP service or a UDP socket for each UDP
service and uses select()
fork() and exec()
ftpd
telnetd
…….
rlogind
16
inetd and its child services
aspendos{korpe}:>
user ppid
root
139
korpe 23440
root 23414
root 19274
root 23401
root 15076
root 21069
root 23377
root 22720
ps -ef
pid
1
0
139 1
139 0
139 0
139 0
139 0
139 0
139 0
139 0
| grep 139
tty
Mar 22 ?
02:15:11 ?
02:14:16 ?
14:26:13 ?
02:13:55 ?
Mar 26 ?
19:00:56 ?
02:13:18 ?
23:16:04 ?
0:07
0:00
0:00
0:00
0:00
0:00
0:00
0:00
0:00
process
/usr/sbin/inetd -s
in.ftpd
in.ftpd
in.rlogind
in.telnetd
in.rlogind
in.telnetd
in.telnetd
in.telnetd
We have a separate child server process for each client.
The parent of these servers is inetd.
17
steps performed by inetd
socket()
For each service listed in
the /etc/inetd.conf file
bind()
listen() (if TCP)
select()
accept() (if TCP)
fork()
close connected socket
(if TCP)
parent
child
close all descriptors
other than socket
Dup socket to descriptors
0, 1, 2 close socket
setgid, setusid
exec() server
18
Wait and Nowait
– For services that uses TCP, when inetd creates a
child process, it does not wait until the child
terminates before accepting a new service
request.
– The child uses a different connected socket than the
listening socket of the inetd.
– For services that uses UDP, when inetd creates
a child process, inetd waits until the child
terminates before accepting a new service
request.
– The child uses the same UDP socket that the inetd was
waiting on for requests.
19
Daytime Server as Daemon invoked by inetd
int main(int argc, char **argv)
{
socklen_t
len;
struct sockaddr * cliaddr;
char
buff[MAXLINE];
time_t
ticks;
extern int
daemon_proc; /* defined in error.c */
void daemon_inetd(const char *pname, int facility)
{
daemon_proc = 1;
openlog(pname, LOG_PID, facility);
}
daemon_inetd(argv[0], 0);
cliaddr = Malloc(MAXSOCKADDR);
len = MAXSOCKADDR;
Getpeername(0, cliaddr, &len);
err_msg("connection from %s", Sock_ntop(cliaddr, len));
ticks = time(NULL);
snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
Write(0, buff, strlen(buff));
Close(0);
exit(0);
We are writing to
descriptor 0 since it
corresponds to the
socket.
(normally it corresponds
to stdin = keyboard)
/* close TCP connection */
}
20