⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manager.c

📁 Minix3.11的源码。[MINIX 3是一个为高可靠性应用而设计的自由且简洁的类UNIX系统。]
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Changes: *   Jul 22, 2005:	Created  (Jorrit N. Herder) */#include "inc.h"#include <unistd.h>#include <sys/types.h>#include <sys/wait.h>#include <minix/dmap.h>/* Allocate variables. */struct rproc rproc[NR_SYS_PROCS];		/* system process table */struct rproc *rproc_ptr[NR_PROCS];		/* mapping for fast access */int nr_in_use; 					/* number of services */extern int errno;				/* error status *//* Prototypes for internal functions that do the hard work. */FORWARD _PROTOTYPE( int start_service, (struct rproc *rp) );FORWARD _PROTOTYPE( int stop_service, (struct rproc *rp,int how) );PRIVATE int shutting_down = FALSE;#define EXEC_FAILED	49			/* recognizable status *//*===========================================================================* *					do_up				     * *===========================================================================*/PUBLIC int do_up(m_ptr)message *m_ptr;					/* request message pointer */{/* A request was made to start a new system service. Dismember the request  * message and gather all information needed to start the service. Starting * is done by a helper routine. */  register struct rproc *rp;			/* system process table */  int slot_nr;					/* local table entry */  int arg_count;				/* number of arguments */  char *cmd_ptr;				/* parse command string */  enum dev_style dev_style;			/* device style */  int s;					/* status variable */  /* See if there is a free entry in the table with system processes. */  if (nr_in_use >= NR_SYS_PROCS) return(EAGAIN);   for (slot_nr = 0; slot_nr < NR_SYS_PROCS; slot_nr++) {      rp = &rproc[slot_nr];			/* get pointer to slot */      if (! rp->r_flags & RS_IN_USE) 		/* check if available */	  break;  }  nr_in_use ++;					/* update administration */  /* Obtain command name and parameters. This is a space-separated string   * that looks like "/sbin/service arg1 arg2 ...". Arguments are optional.   */  if (m_ptr->RS_CMD_LEN > MAX_COMMAND_LEN) return(E2BIG);  if (OK!=(s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR,   	SELF, (vir_bytes) rp->r_cmd, m_ptr->RS_CMD_LEN))) return(s);  rp->r_cmd[m_ptr->RS_CMD_LEN] = '\0';		/* ensure it is terminated */  if (rp->r_cmd[0] != '/') return(EINVAL);	/* insist on absolute path */  /* Build argument vector to be passed to execute call. The format of the   * arguments vector is: path, arguments, NULL.    */  arg_count = 0;				/* initialize arg count */  rp->r_argv[arg_count++] = rp->r_cmd;		/* start with path */  cmd_ptr = rp->r_cmd;				/* do some parsing */   while(*cmd_ptr != '\0') {			/* stop at end of string */      if (*cmd_ptr == ' ') {			/* next argument */          *cmd_ptr = '\0';			/* terminate previous */	  while (*++cmd_ptr == ' ') ; 		/* skip spaces */	  if (*cmd_ptr == '\0') break;		/* no arg following */	  if (arg_count>MAX_NR_ARGS+1) break;	/* arg vector full */          rp->r_argv[arg_count++] = cmd_ptr;	/* add to arg vector */      }      cmd_ptr ++;				/* continue parsing */  }  rp->r_argv[arg_count] = NULL;			/* end with NULL pointer */  rp->r_argc = arg_count;  /* Initialize some fields. */  rp->r_period = m_ptr->RS_PERIOD;  rp->r_dev_nr = m_ptr->RS_DEV_MAJOR;  rp->r_dev_style = STYLE_DEV;   rp->r_restarts = -1; 				/* will be incremented */    /* All information was gathered. Now try to start the system service. */  return(start_service(rp));}/*===========================================================================* *				do_down					     * *===========================================================================*/PUBLIC int do_down(message *m_ptr){  register struct rproc *rp;  pid_t pid = (pid_t) m_ptr->RS_PID;  for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {      if (rp->r_flags & RS_IN_USE && rp->r_pid == pid) {#if VERBOSE	  printf("stopping %d (%d)\n", pid, m_ptr->RS_PID);#endif	  stop_service(rp,RS_EXITING);	  return(OK);      }  }#if VERBOSE  printf("not found %d (%d)\n", pid, m_ptr->RS_PID);#endif  return(ESRCH);}/*===========================================================================* *				do_refresh				     * *===========================================================================*/PUBLIC int do_refresh(message *m_ptr){  register struct rproc *rp;  pid_t pid = (pid_t) m_ptr->RS_PID;  for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {      if (rp->r_flags & RS_IN_USE && rp->r_pid == pid) {#if VERBOSE	  printf("refreshing %d (%d)\n", pid, m_ptr->RS_PID);#endif	  stop_service(rp,RS_REFRESHING);	  return(OK);      }  }#if VERBOSE  printf("not found %d (%d)\n", pid, m_ptr->RS_PID);#endif  return(ESRCH);}/*===========================================================================* *				do_rescue				     * *===========================================================================*/PUBLIC int do_rescue(message *m_ptr){  char rescue_dir[MAX_RESCUE_DIR_LEN];  int s;  /* Copy rescue directory from user. */  if (m_ptr->RS_CMD_LEN > MAX_RESCUE_DIR_LEN) return(E2BIG);  if (OK!=(s=sys_datacopy(m_ptr->m_source, (vir_bytes) m_ptr->RS_CMD_ADDR,   	SELF, (vir_bytes) rescue_dir, m_ptr->RS_CMD_LEN))) return(s);  rescue_dir[m_ptr->RS_CMD_LEN] = '\0';		/* ensure it is terminated */  if (rescue_dir[0] != '/') return(EINVAL);	/* insist on absolute path */  /* Change RS' directory to the rescue directory. Provided that the needed   * binaries are in the rescue dir, this makes recovery possible even if the    * (root) file system is no longer available, because no directory lookups   * are required. Thus if an absolute path fails, we can try to strip the    * path an see if the command is in the rescue dir.    */  if (chdir(rescue_dir) != 0) return(errno);  return(OK);}/*===========================================================================* *				do_shutdown				     * *===========================================================================*/PUBLIC int do_shutdown(message *m_ptr){  /* Set flag so that RS server knows services shouldn't be restarted. */  shutting_down = TRUE;  return(OK);}/*===========================================================================* *				do_exit					     * *===========================================================================*/PUBLIC void do_exit(message *m_ptr){  register struct rproc *rp;  pid_t exit_pid;  int exit_status;#if VERBOSE  printf("RS: got SIGCHLD signal, doing wait to get exited child.\n");#endif  /* See which child exited and what the exit status is. This is done in a   * loop because multiple childs may have exited, all reported by one    * SIGCHLD signal. The WNOHANG options is used to prevent blocking if,    * somehow, no exited child can be found.    */  while ( (exit_pid = waitpid(-1, &exit_status, WNOHANG)) != 0 ) {#if VERBOSE      printf("RS: proc %d, pid %d, ", rp->r_proc_nr, exit_pid);       if (WIFSIGNALED(exit_status)) {          printf("killed, signal number %d\n", WTERMSIG(exit_status));      }       else if (WIFEXITED(exit_status)) {          printf("normal exit, status %d\n", WEXITSTATUS(exit_status));      }#endif      /* Search the system process table to see who exited.        * This should always succeed.        */      for (rp=BEG_RPROC_ADDR; rp<END_RPROC_ADDR; rp++) {          if ((rp->r_flags & RS_IN_USE) && rp->r_pid == exit_pid) {              rproc_ptr[rp->r_proc_nr] = NULL;		/* invalidate */              if ((rp->r_flags & RS_EXITING) || shutting_down) {		  rp->r_flags = 0;			/* release slot */		  rproc_ptr[rp->r_proc_nr] = NULL;	      }	      else if(rp->r_flags & RS_REFRESHING) {		      rp->r_restarts = -1;		/* reset counter */		      start_service(rp);		/* direct restart */	      }              else if (WIFEXITED(exit_status) &&		      WEXITSTATUS(exit_status) == EXEC_FAILED) {		  rp->r_flags = 0;			/* release slot */              }	      else {#if VERBOSE		  printf("Unexpected exit. Restarting %s\n", rp->r_cmd);#endif                  /* Determine what to do. If this is the first unexpected 		   * exit, immediately restart this service. Otherwise use

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -