UNIX网络编程 守护进程和inetd超级服务器

 

守护进程(daemon)是在后台运行且不与任何控制终端关联的进程。

启动守护进程的方法

1)在系统启动阶段,许多守护进程由系统初始化脚本启动,这些脚本通常位于/etc/目录或者以/etc/rc开头的某个

    目录汇总。有若干个网络服务器通常从这些脚本启动:inetd超级服务器

2)许多网络服务器由inetd超级服务器启动。inetd自身由一个脚本启动。inetd监听网络请求(FTP,telnet等)每当

    有一个请求达到时,启动相应的实际服务器(FTP服务器,telnet服务器)

3)cron守护进程按照规则定期执行一些程序,而由它启动执行的程序同样作为守护进程运行。cron自身由

    第一条启动方法中的某个脚本启动

4)at命令一欧诺个鱼指定将来某个时刻的程序执行。这些程序的执行时刻到来时,通常由cron守护进程启动

    执行他们,因此这些程序同样作为守护进程运行。

5)守护进程还可以从用户终端或者再前台或在后台启动。这么做往往是为了测试守护程序或重启因某种原因

   而终止了的某个守护进程

 

 

syslogd守护进程

unix系统中的syslogd守护进程通常由某个系统初始化脚本启动,而且在系统工作期间一直运行。执行步骤如下

1)读取配置文件,通常是/etc/syslog.conf

2)创建一个unix域数据报套接字,给他捆绑的路径是/var/run/log,有些系统是/dev/log

3)创建一个UDP套接字,捆绑到514端口,syslog服务使用的端口

4)打开路径名/dev/klog,来自内核中的任何出错消息都输入到这里

 

//syslog函数
#include <syslog.h>
void syslog(int priority, const char *message, ...);

 本函数中的priority参数是级别(level)和设施(facility)两者的组合

 

openlog的facility参数     

facility 说明
LOG_AUDIT 审计设施
LOG_AUTH 授权程序login,su,getty等
LOG_AUTHPRIV

与LOG_AUTH相同,但写日志文件时

具有权限限制

LOG_CONCOLE 将消息写入/dev/console
LOG_CRON cron和at
LOG_DAEMON 系统守护进程inetd,routed等
LOG_FTP FTP守护进程ftpd
LOG_KERN 内核产生消息
LOG_LOCAL0 保留由本地使用
LOG_LOCAL1 保留由本地使用
LOG_LOCAL2 保留由本地使用
LOG_LOCAL3 保留由本地使用
LOG_LOCAL4 保留由本地使用
LOG_LOCAL5 保留由本地使用
LOG_LOCAL6 保留由本地使用
LOG_LOCAL7 保留由本地使用
LOG_LPR 行式打印机系统lpd,lpc等
LOG_MAIL 邮件系统
LOG_NEWS Usenet网络新闻系统
LOG_NTP 网络时间协议系统
LOG_SECURITY 安全子系统
LOG_SYSLOG syslogd收紧进程本身
LOG_USER 来自掐用户进程的消息(默认)
LOG_UUCP UUCP系统

 

syslog中的level(按序排列)

level 说明
LOG_EMERG 紧急(系统不可使用)(最高优先级)
LOG_ALERT 必须立即修复的情况
LOG_CRIT 严重情况(如硬件设备处错)
LOG_ERR 出错情况
LOG_WARNING 警告情况
LOG_NOTICE 正常但重要的情况
LOG_INFO 信息性消息
LOG_DEBUG 调试消息(最低优先级)

 

//当程序执行失败时,执行下列程序
syslog(LOG_INFO|LOG_LOCAL2, "execute failure");

/etc/syslog.conf配置类似如下

kern.*          /dev/console
local7.debug /var/log/cisco.log
所有内核的消息都输出到控制台
所有local7的debug几倍消息都输出到 cisco.log文件中

 

//进程也可以调用下面两个函数
//openlog可以在首次调用syslog前调用
//closelog可以再应用进程不再需要发送日志消息时调用
#include <syslog.h>
void openlog(const char *ident, int options, int facility);
void closelog(void);

 

syslog的 openlog函数的option参数

option 说明
LOG_CONS 若日志消息不能通过UNXI域数据报发送至syslogd,则将消息写至控制台
LOG_NEDLAY

立即打开至syslogd守护进程的UNIX域数据报套接字,不要等到第一条消息已经被记录时

再打开。通常在记录第一条消息之前,不打开该套接字

LOG_NOWAIT

不要等待在将消息记入日志过程中可能已创建的子进程。因为再syslog调用wait时,应用

程序可能已获得了子进程的状态,这种处理阻止了与捕捉SIGCHLD信号的应用程序之间

产生的冲突

LOG_ODELAY 在第一条消息被记录之前延迟打开至syslogd守护进程的连接
LOG_PERROR 除将日志消息发送给syslogd外,还将它写至标准出错(在Solaris上不可用)
LOG_PID

记录每条消息都要包含进程ID,此选项可供对每个不同的请求都fork一个子进程的守护

进程使用(与从不调用fork的守护进程相比较,如syslogd)

 

 

inetd守护进程

典型的unix系统可能存在许多服务器,他们只是等待客户请求的达到,如FTP,telnet等。所有这些服务都有一个进程与之关联。这些进程都是从/etc/rc文件中启动。而且每个进程执行几乎相同的启动任务:创建一个套接字,把本服务器的众所周知端口捆绑到该套接字,等待一个连接。

这个模型存在两个问题

1)所有这些守护进程含有几乎相同的启动代码,既表现在创建套接字上,也表现在演变成守护进程上

2)每个守护进程再进程表中占据一个表项,然后他们大部分时间处于睡眠状态

 

使用一个特殊的inetd超级服务器解决上述问题

1)通过由inetd处理普通守护进程的大部分启动细节以简化守护进程的编写。

2)单个进程(inetd)就能为多个服务等待外来的客户请求,以此取代每个服务一个进程的做法,这么做减少了

    系统中的进程总数

 

/etc/xinetd.d 目录下配置文件各字段解释

字段 说明
service-name 必须在/etc/services文件中定义
socket-type stream(对于TCP)或者dgram(对于UDP)
protocol 必须在/etc/protocols文件中定义
wait-flag 对于TCP一般为nowait,对于UDP是wait
login-name 来自/etc/passwd的用户名,一般为root
server-program 调用exec指定的完整路径名
server-program-arguments 调用exec指定的命令行参数

 

inetd的工作流程


工作步骤

1)在启动阶段,读取/etc/xinetd.d 目录下的文件并为每个服务创建一个适当类型的套接字

2)为每个端口调用bind,指定捆绑相应服务器的总所周知端口和统配地址,这个TCP或者UDP端口号通告

   getserverbyname获得

3)对于每个TCP套接字,调用listen以接受外来的连接请求

4)创建完所有套接字后,调用select等待其中任何一个套接字变为可读。inetd大部分时间都阻塞在select调用上

5)当select返回指出魔木格套接字可读之后,如果该套接字是一个TCP套接字,而且其服务器的wait-flag值为

    nowait那就调用accept接受这个新连接

6)inetd守护进程调用fork派生进程,并由子进程处理服务请求,这一点类似标志的并发服务器

7)如果第五部中select返回的是是一个字节流套接字,那么父进程必须关闭已连套接字。父进程再次调用select

    等待下一个变为可读的套接字

 

 

 

 

 

 

 

 

参考

UNP Chapter 12 - 守护进程和inetd超级服务器

 

 

 

 

 

 

 

猜你喜欢

转载自xxniao.iteye.com/blog/2258942
今日推荐