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 ...
随机推荐
- viewpager的滑动
在一个已经是月黑风高快下班的时刻了,我们产品突然通知我们开会,要添加一个功能,他闲来无聊随便戳了戳facebook,说点开联系人的那个横向滑动的卡片式的效果不错,让我们在我们的app里添加这个效果,我 ...
- Cocos 2d-X Lua 游戏添加苹果内购(二) OC和Lua交互代码详解
这是第二篇 Cocos 2d-X Lua 游戏添加苹果内购(一) 图文详解准备流程 这是前面的第一篇,详细的说明了怎样添加内购项目以及填写银行信息提交以及沙盒测试员的添加使用以及需要我们注意的东西,结 ...
- Linux系列教程(四)——Linux文件和目录处理命令
这个系列教程的前面我们讲解了如何安装Linux系统,以及学习Linux系统的一些方法.那么从这篇博客开始,我们就正式进入Linux命令的学习.学习命令,首先要跟大家纠正的一点就是,我们不需要记住每一条 ...
- Java基础-流程控制(04)
在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的.也就是说程序的流程对运行结果有直接的影响.所以,我们必须清楚每条语句的执行流程.而且,很多时候我们要通过控制语句的执行顺序来实现我 ...
- 【20171028早】ubuntu 16.04 LTS 安装php遇到的问题
背景: 10月28日的一个早上,老黑一如往常地练习,我测试不破坏,当时我找到sqli-libs 游戏,可是我没有立即开始,于是,奇妙的事情就由php开始了.ubuntu16.04安装相关环境 apac ...
- Mysql 用户,权限管理的几点理解。
前两天项目数据库要移植到mysql,为此临时抓了几天很久没用的mysql. 公司的数据库比较简单,从oracle迁移到mysql很简单,但是,中间的权限管理让我感觉既简单又复杂..简单是因为网上关于m ...
- RobotFrameWork安装笔记
1. RobotFrameWork安装配置笔记 1.1. 安装环境 64位win10家庭中文版 网上很多这方面的教程,但是比较零散,这里是自己安装配置的一个简单的笔记. 1.2. 安装说明 由于R ...
- Python之qq邮件
用python发送电子邮件验证这个功能,可以说花费了我很久时间,这也是为什么我重头敲了之前的两遍代码.不要说我傻,仅仅是笨了一点而已 ^.- . 之前我所参考是如何发送 GMail. 但是我并不想这么 ...
- ASP.NET Core 认证与授权[4]:JwtBearer认证
在现代Web应用程序中,通常会使用Web, WebApp, NativeApp等多种呈现方式,而后端也由以前的Razor渲染HTML,转变为Stateless的RESTFulAPI,因此,我们需要一种 ...
- 异常详细信息: Abp.AbpException: No language defined!
程序运行后,出现错误:No language defined! 解决方法: 1.检查是否已创建数据库,若未创建则在程序包管理控制台执行命令:Update-Database 2.检查表AbpLangua ...