Linux系统启动在inittab和rc里面添加启动程序问题

原创 2016年08月31日 11:42:12

一般linux系统中,系统启动时,内核的启动的最后启动了用户空间的第一个进程init,这个进程的最后会执行/etc/inittab中的命令

一般inittab命令如下

console::sysinit:/etc/init.d/rcS
#ttyS0::askfirst:-/bin/sh
::respawn:-/bin/login
sysinit是启动时执行一次的程序

respawn是启动这个进程,如果这个进程挂了,重新启动它

看一下init进程最后对inittab的处理

	/* Now run everything that needs to be run */
	/* First run the sysinit command */
	run_actions(SYSINIT);
	check_delayed_sigs();
	/* Next run anything that wants to block */
	run_actions(WAIT);
	check_delayed_sigs();
	/* Next run anything to be run only once */
	run_actions(ONCE);

	/* Now run the looping stuff for the rest of forever.
	 */
	while (1) {
		int maybe_WNOHANG;

		maybe_WNOHANG = check_delayed_sigs();

		/* (Re)run the respawn/askfirst stuff */
		run_actions(RESPAWN | ASKFIRST);
		maybe_WNOHANG |= check_delayed_sigs();

		/* Don't consume all CPU time - sleep a bit */
		sleep(1);
		maybe_WNOHANG |= check_delayed_sigs();

		/* Wait for any child process(es) to exit.
		 *
		 * If check_delayed_sigs above reported that a signal
		 * was caught, wait will be nonblocking. This ensures
		 * that if SIGHUP has reloaded inittab, respawn and askfirst
		 * actions will not be delayed until next child death.
		 */
		if (maybe_WNOHANG)
			maybe_WNOHANG = WNOHANG;
		while (1) {
			pid_t wpid;
			struct init_action *a;

			/* If signals happen _in_ the wait, they interrupt it,
			 * bb_signals_recursive_norestart set them up that way
			 */
			wpid = waitpid(-1, NULL, maybe_WNOHANG);
			if (wpid <= 0)
				break;

			a = mark_terminated(wpid);
			if (a) {
				message(L_LOG, "process '%s' (pid %d) exited. "
						"Scheduling for restart.",
						a->command, wpid);
			}
			/* See if anyone else is waiting to be reaped */
			maybe_WNOHANG = WNOHANG;
		}
	} /* while (1) */
}
可以看到程序只启动一次SYSINIT,RESPAWN则放到了while(1)中。

/* Run all commands of a particular type */
static void run_actions(int action_type)
{
	struct init_action *a;

	for (a = init_action_list; a; a = a->next) {
		if (!(a->action_type & action_type))
			continue;

		if (a->action_type & (SYSINIT | WAIT | ONCE | CTRLALTDEL | SHUTDOWN)) {
			pid_t pid = run(a);
			if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN))
				waitfor(pid);
		}
		if (a->action_type & (RESPAWN | ASKFIRST)) {
			/* Only run stuff with pid == 0. If pid != 0,
			 * it is already running
			 */
			if (a->pid == 0)
				a->pid = run(a);
		}
	}
}

需要注意一个细节,当执行SYSINIT时,父进程会waitfor(pid),等待子进程执行完成。
如果系统启动时需要启动自己程序,一般在/etc/init.d/rcS里面添加一个脚本,通过脚本启动程序。

而启动程序的最后启动一个命令行程序,而这个程序是不会退出的。

那就有问题了,从上面init进程的启动顺序,while(1)里面就执行不到了,无法检查信号和进行子进程的资源回收。

所以在/etc/init.d/rcS里面执行不退出的启动程序是不靠谱的。

那就需要在后面的RESPAWN命令做工作了,修改inittab

::respawn:-/bin/HHlogin
改为自己的HHlogin,在HHlogin中判断是否有启动程序,如果有则执行,如果没有则启动自己的/bin/login

程序如下

/*
*  COPYRIGHT NOTICE
*  Copyright (C) 2016 HuaHuan Electronics Corporation, Inc. All rights reserved
*
*  Author       	:Kevin_fzs
*  File Name        	:/home/kevin/works/projects/IPRAN/drivers/inittab/HHlogin.c
*  Create Date        	:2016/08/11 17:37
*  Last Modified      	:2016/08/11 17:37
*  Description    	:
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

#define HOME_BIN_AUTORUN	"/home/bin/autorun.sh"
#define HOME_BIN_VTYSH		"/home/bin/vtysh"
#define BIN_LOGIN		"/bin/login"
#define BIN_SH			"/bin/sh"

#define START_LINUXSH	0	
#define START_VTYSH	1	

int execute_and_wait(int opt)
{
	pid_t cpid;
	int status;

	if(START_LINUXSH == opt)
	{
		char *argv[]={BIN_LOGIN, NULL};
		int ret =execv(BIN_LOGIN, argv);

		_exit(1);

	}
	if(START_VTYSH == opt)
	{
		cpid = fork();

		if(cpid == 0) //child 
		{
			char *argv[]={HOME_BIN_VTYSH, NULL};
			int ret =execv(HOME_BIN_VTYSH, argv);
	
			_exit(1);
		}
		else //father 
		{
			/*status 低8bits是信号,高8bits记录exit的返回值*/
			/*当正常返回的时候,waitpid返回收集到的子进程的进程ID*/
			int ret = waitpid(cpid,&status,0);
			printf("\nvtysh exit,return code:[status=0x%x][pid=%d]\n", status, ret);
			usleep(10000);
			exit(0);
		}

	}
}

static void
vtysh_signal_set (int signo, void (*func)(int))
{
  struct sigaction sig;
  struct sigaction osig;

  sig.sa_handler = func;
  sigemptyset (&sig.sa_mask);
  sig.sa_flags = 0;
#ifdef SA_RESTART
  sig.sa_flags |= SA_RESTART;
#endif /* SA_RESTART */

  sigaction (signo, &sig, &osig);
}

void vtysh_signal_init ()
{
  vtysh_signal_set (SIGINT, SIG_IGN);
  vtysh_signal_set (SIGTERM, SIG_IGN);
  vtysh_signal_set (SIGQUIT, SIG_IGN);
}

int main()
{
	char *argv[]={NULL};

	/*we must ignor SIGINT*/
	vtysh_signal_init ();
	if((!access(HOME_BIN_AUTORUN, 0))&&(!access(HOME_BIN_VTYSH, 0)))
	{
		printf("App is existent, startup...\n");
//		signal(SIGINT, SIG_DFL);
		execute_and_wait(START_VTYSH);
	}
	else
		execute_and_wait(START_LINUXSH);

	return 0;
}





上面的程序是针对我们产品的一下启动脚本和程序,如果使用还需适当修改







版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

开机启动脚本/etc/init.d/rcS

借助启动脚本可以设置各种程序开机后自动运行,也可以设置其他系统设置,这有点 类似于Windows 系统中的Autobat 自动批处理文件,启动脚本的位于板子的/etc/init.d/rcS,内 ...

Linux 开机脚本启动顺序--inittab脚本启动解析

Linux 开机脚本启动顺序:  第一步:启动内核 第二步:执行init (配置文件/etc/inittab) 第三步:启动相应的脚本,执行inittab脚本,并且执行里面的脚本/etc/ini...

Linux文件系统启动过程及login的实现

1. busybox简介 busybox是一个集成了一百多个最常用linux命令和工具的软件,它将许多常用的LINUX命令和工具结合到了一个单独的可执行程序中。虽然与相应的GNU工具比较起来,b...
  • cl11010
  • cl11010
  • 2014年04月25日 17:03
  • 16324

BusyBox init及inittab文件详解

原文链接http://blog.csdn.net/yangruibao/article/details/7435182 由于BusyBox自身的一些特点,BusyBox init非常适合在嵌入式系...

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。 1.   最基本的算法是,从小到大遍历: for (i = 2 to A -1)          if (i * B > A)...

利用K-means聚类算法根据经纬度坐标对中国省市进行聚类

K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...

Radon变换理论介绍与matlab实现--经验交流

本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。 Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...

CT图像重建技术

由于csdn贴图不方便,并且不能上传附件,我把原文上传到了资源空间CT图像重建技术 1.引言 计算机层析成像(Computed Tomography,CT)是通过对物体进行不同角度的射线投影测量而...

Matlab绘图-很详细,很全面

Matlab绘图强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Ma...

linux查找目录下的所有文件中是否含有某个字符串

查找目录下的所有文件中是否含有某个字符串  find .|xargs grep -ri "IBM"  查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名  find .|xargs g...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux系统启动在inittab和rc里面添加启动程序问题
举报原因:
原因补充:

(最多只允许输入30个字)