daemon 启动system V init 和 systemd 配置
先试着写一个udpserver的daemon
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 4444
#define FDMAX 64
void initdaemon();
int main()
{
#ifdef DAEMON
initdaemon();
#endif
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if(fd < 0)
return -1;
struct sockaddr_in server, client;
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
bind(fd, (const struct sockaddr *)&server, sizeof(struct sockaddr));
socklen_t len = sizeof(struct sockaddr);
char buff[2048] = {0};
while(1)
{
recvfrom(fd, buff, 2048, 0,(struct sockaddr *)&client, &len);
// printf("%s send msg: %s \n", inet_ntoa(client.sin_addr), buff);
sendto(fd, "OK", 2, 0, (const struct sockaddr *)&client, len);
}
}
void initdaemon()
{
pid_t pid = fork(); //第一次fork 是因为创建会话的进程不能是进程组长,否则setsid会失败。
if(pid > 0)
{
_exit(0);
}
else if(pid < 0)
{
_exit(1);
}
if(setsid() < 0)
_exit(1);
pid_t id = fork();//第二次fork是因为当前进程是会话组长 他有可能会获取控制终端,为了不让它获得控制终端,不让它成为组长。
if(id > 0){
_exit(0);
}
else if(id < 0)
{
_exit(1);
}
int i = 0;
chdir("/");
for(i; i < FDMAX; ++i)
close(i);
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDWR);
open("/dev/null", O_RDWR); //将0 1 2重定向
}
gcc -DDAEMON udpserver.c -o udpserver添加宏DAEMON进行编译
下面是测试client端:
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#define PORT 4444
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("./udpclient IP\n");
return 1;
}
int fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
return 1;
struct sockaddr_in server;
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
if (!inet_pton(AF_INET, argv[1], (void *)&server.sin_addr))
{
printf("IP error\n");
return -1;
}
char buff1[2048] ="sdfsdf";
char buff2[2048] = {0};
socklen_t size = sizeof(struct sockaddr);
while(1)
{
sendto(fd, buff1, 2048, (const struct sockaddr *)&server, size);
sleep(5);
recvfrom(fd, buff2, 2048, 0, NULL, NULL);
printf("recv : %s\n", buff2);
}
}
先看一下system v init管理服务的一种写法:
我们可以看到在/etc/init.d 下面有很多脚本文件, 当系统启动时,init进程会根据不同的运行级别去执行不同的/etc/rcN.d 里面的脚本文件并会自动加上start参数,我们看一下sshd的例子:
set -e
# /etc/init.d/ssh: start and stop the OpenBSD "secure shell(tm)" daemon
test -x /usr/sbin/sshd || exit 0
( /usr/sbin/sshd -\? 2>&1 | grep -q OpenSSH ) 2>/dev/null || exit 0
umask 022
if test -f /etc/default/ssh; then
. /etc/default/ssh
fi
略
case "$1" in
start)
check_for_upstart 1
check_privsep_dir
check_for_no_start
check_dev_null
log_daemon_msg "Starting OpenBSD Secure Shell server" "sshd" || true
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
log_end_msg 0 || true
else
log_end_msg 1 || true
fi
;;
stop)
check_for_upstart 0
log_daemon_msg "Stopping OpenBSD Secure Shell server" "sshd" || true
if start-stop-daemon --stop --quiet --oknodo --pidfile /var/run/sshd.pid; then
log_end_msg 0 || true
else
log_end_msg 1 || true
fi
;;
reload|force-reload)
check_for_upstart 1
check_for_no_start
check_config
log_daemon_msg "Reloading OpenBSD Secure Shell server's configuration" "sshd" || true
if start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd; then
log_end_msg 0 || true
else
log_end_msg 1 || true
fi
;;
restart)
check_for_upstart 1
check_privsep_dir
check_config
log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd" || true
start-stop-daemon --stop --quiet --oknodo --retry 30 --pidfile /var/run/sshd.pid
check_for_no_start log_end_msg
check_dev_null log_end_msg
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
log_end_msg 0 || true
else
log_end_msg 1 || true
fi
;;
try-restart)
check_for_upstart 1
check_privsep_dir
check_config
log_daemon_msg "Restarting OpenBSD Secure Shell server" "sshd" || true
RET=0
start-stop-daemon --stop --quiet --retry 30 --pidfile /var/run/sshd.pid || RET="$?"
case $RET in
0)
# old daemon stopped
check_for_no_start log_end_msg
check_dev_null log_end_msg
if start-stop-daemon --start --quiet --oknodo --pidfile /var/run/sshd.pid --exec /usr/sbin/sshd -- $SSHD_OPTS; then
log_end_msg 0 || true
else
log_end_msg 1 || true
fi
;;
1)
# daemon not running
log_progress_msg "(not running)" || true
log_end_msg 0 || true
;;
*)
# failed to stop
log_progress_msg "(failed to stop)" || true
log_end_msg 1 || true
;;
esac
;;
status)
check_for_upstart 1
status_of_proc -p /var/run/sshd.pid /usr/sbin/sshd sshd && exit 0 || exit $?
;;
*)
log_action_msg "Usage: /etc/init.d/ssh {start|stop|reload|force-reload|restart|try-restart|status}" || true
exit 1
esac
exit 0
写法也就是大致这个样子的利用shell 里的case 给不同参数运行不同的function 至于start-stop-daemon的用法可以查阅man page。
我们就可以将我们的udpserver 放到/usr/bin/目录下面,然后在/etc/init.d/目录下加上udp_server 脚本文件写法如下:
#!/bin/bash
SERVER=/usr/bin/udpserver
if [ ! -e $SERVER ];then
exit 1
fi
case "$1" in
start)
if [ -n "`pidof $SERVER`" ];then
echo "Udpserver is running......"
else
$SERVER
fi
;;
stop)
PID=`pidof /usr/bin/udpserver`
[ -n "$PID" ] && kill -9 $PID
;;
restart)
PID=`pidof $SERVER`
[ -n "$PID" ] && kill -9 $PID
$SERVER
;;
*)
exit 1
;;
esac
再将你需要运行的等级目录下添加连接/etc /rc2.d/目录下K开头表示不启动服务,S打头表示启动服务 建立连接 ln -s ../init.d/udp_server S99udpserver , 表名开机启动 S后的数字字母等表示启动顺序。如此就可以实现system v init类型的启动服务。
若以systemd形式 将更为简单方便 此时就不需要udpserver 是一个daemon 可去掉宏进行编译。
在/etc/systemd/system/下建立文件udpserver.service 文件 内容大概为
[Unit]
Description=my dup server
After=network.target
[Service]
EnvironmentFile=
ExecStart=/usr/bin/udpserver
ExecReload=/bin/killall udpserver
KillMode=process
Restart=on-failure
[Install]
WantedBy=multi-user.target
然后再执行 systemctl daemon-reload systemctl enable udpserver即可开机自启动。
systemctl start /stop/reload控制服务。journalctl可以查看启动日志。
总得来说还是systemd这种形式较为简单,它还有较好的日志系统,方便管理 不用将服务写为daemon。
daemon 启动system V init 和 systemd 配置的更多相关文章
- 编写CentOS的System V init启动脚本
系统本身自带了说明,在/usr/share/doc/initscripts-(*)/sysvinitfiles,内容如下: 所有System V init脚本都命名为/etc/rc.d/init.d/ ...
- Systemd初始化进程/RHEL 6系统中System V init命令与RHEL 7系统中systemctl命令的对比
Linux操作系统的开机过程是这样的,即从BIOS开始,然后进入Boot Loader,再加载系统内核,然后内核进行初始化,最后启动初始化进程.初始化进程作为Linux系统的第一个进程,它需要完成Li ...
- systemd、upstart和system V
http://blog.csdn.net/kumu_linux/article/details/7653802 systemd是Linux下的一种init软件,由Lennart Poettering ...
- Linux system V
Sysvinit 的小结 Sysvinit 的优点是概念简单.Service 开发人员只需要编写启动和停止脚本,概念非常清楚:将 service 添加/删除到某个 runlevel 时,只需要执行一些 ...
- /etc/init.d/sshd配置SSHD路径忘记修改导致启动失败
[root@lnlte2dmr3 ~]# bash[root@lnlte2dmr3 ~]# install -v -m700 -d /var/empty/sshdinstall: 正在创建目录&quo ...
- Linux启动流程和服务管理(init和systemd)
目录 一:Linux启动流程 init和Systemd的区别 二:Linux服务管理(service,systemctl) 一:Linux启动流程 Rhel6启动过程: Rhel7启动过程: GRUB ...
- Linux init 系列一 System V风格
传统的Linux init有两种风格,System V风格和BSD风格,本文主要介绍System V风格. System V风格init的主要流程是, 1. 内核执行init进程. 2. Init 运 ...
- System V启动脚本启动的服务
/etc/rc.d/init.d/目录下的内容如下:这些常用的服务器都是System v的服务,要控制System V 的服务,我们可以使用以下命令 #/etc/rc.d/init.d/script ...
- 提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll
新版本SQLITE,如果下载Precompiled Binaries版会出现提示“应用程序无法启动,因为应用程序的并行配置不正确”不能加载 System.Data.SQLite.dll. 下载Prec ...
随机推荐
- 如何用CropBox实现头像裁剪并与java后台交互
如何用CropBox实现头像裁剪并与java后台交互 参考网站:https://developer.mozilla.org/zh-CN/docs/Web/API/Blob 参考: http://blo ...
- Java基础-方法(07)
方法的定义 方法其实就是完成特定功能的代码块在很多语言里面都有函数的定义函数在Java中被称为方法 格式: 修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2…) { 函数体; ret ...
- 【译】Java中的字符串字面量
原文地址:https://javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html 作者:Corey McGlone 让我们由一个简 ...
- js如何获取地址栏的参数
//获取参数的方法(利用正则表达式) function GetUrlParam(name){ var reg = new RegExp("(^|&)"+ name +&qu ...
- IIS 服务无法在此时接受控制信息
应用程序池无法重新启动,报错:服务无法在此时接受控制信息 解决方法:重启 Credential Manager服务即可
- route命令实例练习
第1章 命令配置 虚拟服务器 网卡配置信息 虚拟网卡名称 虚拟网卡模式 服务器01 eth1 10.0.0.10/24 nat模式 服务器02 eth2 10.0.0.11/24 nat模式 eth3 ...
- 特征提取方法: one-hot 和 IF-IDF
one-hot 和 IF-IDF是目前最为常见的用于提取文本特征的方法,本文主要介绍两种方法的思想以及优缺点. 1. one-hot 1.1 one-hot编码 什么是one-hot编码?one-ho ...
- cookie在不同域名domain、path下的读取规则
cookie 子域名可以读父域名中的cookie 如在 .ping.com域下注入cookie,则该子域下的网页如p1.ping.com.p2.ping.com 都能读取到cookie信息 path的 ...
- 高性能 AJAX
请求数据的常用的五种方式 1.XMLHttpRequest (XHR) var url = '/data.php'; var params = [ 'id=934875', 'limi ...
- 一个“”字引发的痛苦经历
(一篇老文章,还有点价值,特意整理了一下.由于涉及客户项目,已经进行了脱敏处理) 1 写在前面的话 虽然这个问题是有解决方案的,但我不建议大家提供给客户,理由见此. 2 问题描述 2010.10.12 ...