Example #1
0
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
PUBLIC int main()
{
    /* Main routine of the process manager. */
    int result, s, proc_nr;
    struct mproc *rmp;
    sigset_t sigset;

    pm_init();			/* initialize process manager tables */

    /* This is PM's main loop-  get work and do it, forever and forever. */
    while (TRUE) {
        get_work();		/* wait for an PM system call */

        /* Check for system notifications first. Special cases. */
        if (call_nr == SYN_ALARM) {
            pm_expire_timers(m_in.NOTIFY_TIMESTAMP);
            result = SUSPEND;		/* don't reply */
        } else if (call_nr == SYS_SIG) {	/* signals pending */
            sigset = m_in.NOTIFY_ARG;
            if (sigismember(&sigset, SIGKSIG))  (void) ksig_pending();
            result = SUSPEND;		/* don't reply */
        }
        /* Else, if the system call number is valid, perform the call. */
        else if ((unsigned) call_nr >= NCALLS) {
            result = ENOSYS;
        } else {
            result = (*call_vec[call_nr])();
        }

        /* Send the results back to the user to indicate completion. */
        if (result != SUSPEND) setreply(who, result);

        swap_in();		/* maybe a process can be swapped in? */

        /* Send out all pending reply messages, including the answer to
         * the call just made above.  The processes must not be swapped out.
         */
        for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
            /* In the meantime, the process may have been killed by a
             * signal (e.g. if a lethal pending signal was unblocked)
             * without the PM realizing it. If the slot is no longer in
             * use or just a zombie, don't try to reply.
             */
            if ((rmp->mp_flags & (REPLY | ONSWAP | IN_USE | ZOMBIE)) ==
                    (REPLY | IN_USE)) {
                if ((s=send(proc_nr, &rmp->mp_reply)) != OK) {
                    panic(__FILE__,"PM can't reply to", proc_nr);
                }
                rmp->mp_flags &= ~REPLY;
            }
        }
    }
    return(OK);
}
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
PUBLIC void main()
{
/* Main routine of the memory manager. */

  int result, proc_nr;
  struct mproc *rmp;

  mm_init();			/* initialize memory manager tables */

  /* This is MM's main loop-  get work and do it, forever and forever. */
  while (TRUE) {
	get_work();		/* wait for an MM system call */

	/* If the call number is valid, perform the call. */
	if ((unsigned) mm_call >= NCALLS) {
		result = ENOSYS;
	} else {
		result = (*call_vec[mm_call])();
	}

	/* Send the results back to the user to indicate completion. */
	if (result != E_NO_MESSAGE) setreply(who, result);

	swap_in();		/* maybe a process can be swapped in? */

	/* Send out all pending reply messages, including the answer to
	 * the call just made above.  The processes must not be swapped out.
	 */
	for (proc_nr = 0, rmp = mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
		if ((rmp->mp_flags & (REPLY | ONSWAP)) == REPLY) {
			if (send(proc_nr, &rmp->mp_reply) != OK)
				panic("MM can't reply to", proc_nr);
			rmp->mp_flags &= ~REPLY;
		}
	}
  }
}
Example #3
0
/*===========================================================================*
 *				do_srv_fork				     *
 *===========================================================================*/
PUBLIC int do_srv_fork()
{
/* The process pointed to by 'mp' has forked.  Create a child process. */
  register struct mproc *rmp;	/* pointer to parent */
  register struct mproc *rmc;	/* pointer to child */
  int s;
  pid_t new_pid;
  static int next_child;
  int i, n = 0;
  endpoint_t child_ep;
  message m;

  /* Only RS is allowed to use srv_fork. */
  if (mp->mp_endpoint != RS_PROC_NR)
	return EPERM;

 /* If tables might fill up during FORK, don't even start since recovery half
  * way through is such a nuisance.
  */
  rmp = mp;
  if ((procs_in_use == NR_PROCS) || 
  		(procs_in_use >= NR_PROCS-LAST_FEW && rmp->mp_effuid != 0))
  {
  	printf("PM: warning, process table is full!\n");
  	return(EAGAIN);
  }

  /* Find a slot in 'mproc' for the child process.  A slot must exist. */
  do {
        next_child = (next_child+1) % NR_PROCS;
	n++;
  } while((mproc[next_child].mp_flags & IN_USE) && n <= NR_PROCS);
  if(n > NR_PROCS)
	panic("do_fork can't find child slot");
  if(next_child < 0 || next_child >= NR_PROCS
 || (mproc[next_child].mp_flags & IN_USE))
	panic("do_fork finds wrong child slot: %d", next_child);

  if((s=vm_fork(rmp->mp_endpoint, next_child, &child_ep)) != OK) {
	printf("PM: vm_fork failed: %d\n", s);
	return s;
  }

  rmc = &mproc[next_child];
  /* Set up the child and its memory map; copy its 'mproc' slot from parent. */
  procs_in_use++;
  *rmc = *rmp;			/* copy parent's process slot to child's */
  rmc->mp_parent = who_p;			/* record child's parent */
  if (!(rmc->mp_trace_flags & TO_TRACEFORK)) {
	rmc->mp_tracer = NO_TRACER;		/* no tracer attached */
	rmc->mp_trace_flags = 0;
	(void) sigemptyset(&rmc->mp_sigtrace);
  }
  /* inherit only these flags */
  rmc->mp_flags &= (IN_USE|PRIV_PROC|DELAY_CALL);
  rmc->mp_child_utime = 0;		/* reset administration */
  rmc->mp_child_stime = 0;		/* reset administration */
  rmc->mp_exitstatus = 0;
  rmc->mp_sigstatus = 0;
  rmc->mp_endpoint = child_ep;		/* passed back by VM */
  for (i = 0; i < NR_ITIMERS; i++)
	rmc->mp_interval[i] = 0;	/* reset timer intervals */

  /* Find a free pid for the child and put it in the table. */
  new_pid = get_free_pid();
  rmc->mp_pid = new_pid;	/* assign pid to child */

  m.m_type = PM_SRV_FORK;
  m.PM_PROC = rmc->mp_endpoint;
  m.PM_PPROC = rmp->mp_endpoint;
  m.PM_CPID = rmc->mp_pid;

  tell_vfs(rmc, &m);

  /* Tell the tracer, if any, about the new child */
  if (rmc->mp_tracer != NO_TRACER)
	sig_proc(rmc, SIGSTOP, TRUE /*trace*/, FALSE /* ksig */);

  /* Wakeup the newly created process */
  setreply(rmc-mproc, OK);

  return rmc->mp_pid;
}
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
int main()
{
/* Main routine of the process manager. */
  int result;

  /* SEF local startup. */
  sef_local_startup();
  
  
// Initialization of the semarray (of pointers) to NULL
  
  register struct mproc *rmp;
  
// rmp is the pointer to the struct of the process table

    	 for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
    	 
    	 {
    				 for(int i=0; i<12; i++) // for all 12 semaphores
    				  {
    					  rmp->semarray[i]=NULL;
    				  }
    				  
    	  }

  // end of Initialization
  

/* This is PM's main loop-  get work and do it, forever and forever. */
  
while (TRUE) {
	  int ipc_status;

	  /* Wait for the next message and extract useful information from it. */
	  if (sef_receive_status(ANY, &m_in, &ipc_status) != OK)
		  panic("PM sef_receive_status error");
	  who_e = m_in.m_source;	/* who sent the message */
	  if(pm_isokendpt(who_e, &who_p) != OK)
		  panic("PM got message from invalid endpoint: %d", who_e);
	  call_nr = m_in.m_type;	/* system call number */

	  /* Process slot of caller. Misuse PM's own process slot if the kernel is
	   * calling. This can happen in case of synchronous alarms (CLOCK) or or
	   * event like pending kernel signals (SYSTEM).
	   */
	  mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p];
	  if(who_p >= 0 && mp->mp_endpoint != who_e) {
		  panic("PM endpoint number out of sync with source: %d",
				  			mp->mp_endpoint);
	  }

	/* Drop delayed calls from exiting processes. */
	if (mp->mp_flags & EXITING)
		continue;

	/* Check for system notifications first. Special cases. */
	if (is_ipc_notify(ipc_status)) {
		if (who_p == CLOCK) {
			expire_timers(m_in.NOTIFY_TIMESTAMP);
		}

		/* done, send reply and continue */
		sendreply();
		continue;
	}

	switch(call_nr)
	{
	case PM_SETUID_REPLY:
	case PM_SETGID_REPLY:
	case PM_SETSID_REPLY:
	case PM_EXEC_REPLY:
	case PM_EXIT_REPLY:
	case PM_CORE_REPLY:
	case PM_FORK_REPLY:
	case PM_SRV_FORK_REPLY:
	case PM_UNPAUSE_REPLY:
	case PM_REBOOT_REPLY:
	case PM_SETGROUPS_REPLY:
		if (who_e == VFS_PROC_NR)
		{
			handle_vfs_reply();
			result= SUSPEND;		/* don't reply */
		}
		else
			result= ENOSYS;
		break;
	case COMMON_GETSYSINFO:
		result = do_getsysinfo();
		break;
	default:
		/* Else, if the system call number is valid, perform the
		 * call.
		 */
		if ((unsigned) call_nr >= NCALLS) {
			result = ENOSYS;
		} else {
#if ENABLE_SYSCALL_STATS
			calls_stats[call_nr]++;
#endif

			result = (*call_vec[call_nr])();

		}
		break;
	}

	/* Send reply. */
	if (result != SUSPEND) setreply(who_p, result);
	sendreply();
  }
  return(OK);
}
Example #5
0
int
main(int argc, char *argv[])
{
	int ch, iflag, flags;
	struct passwd *pw;
	time_t interval;
	struct stat sb;
	ALIAS *cur;

	opterr = iflag = 0;
	interval = -1;
	while ((ch = getopt(argc, argv, "a:Iir:")) != -1)
		switch ((char)ch) {
		case 'a':			/* alias */
			if (!(cur = (ALIAS *)malloc((u_int)sizeof(ALIAS))))
				break;
			cur->name = optarg;
			cur->next = names;
			names = cur;
			break;
		case 'I':			/* backward compatible */
		case 'i':			/* init the database */
			iflag = 1;
			break;
		case 'r':
			if (isdigit((unsigned char)*optarg)) {
				interval = atol(optarg) * SECSPERDAY;
				if (interval < 0)
					usage();
			} else
				interval = 0;	/* one time only */
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc != 1) {
		if (!iflag)
			usage();
		if (!(pw = getpwuid(getuid()))) {
			syslog(LOG_ERR,
			    "no such user uid %u.", getuid());
			exit(1);
		}
	} else if (!(pw = getpwnam(*argv))) {
		syslog(LOG_ERR, "no such user %s.", *argv);
		exit(1);
	}
	if (chdir(pw->pw_dir)) {
		syslog(LOG_NOTICE,
		    "no such directory %s.", pw->pw_dir);
		exit(1);
	}

	/*
	 * dbopen(3) can not deal with a zero-length file w/o O_TRUNC.
	 */
	if (iflag == 1 || (stat(VDB, &sb) == 0 && sb.st_size == (off_t)0))
		flags = O_CREAT|O_RDWR|O_TRUNC;
	else
		flags = O_CREAT|O_RDWR;

	db = dbopen(VDB, flags, S_IRUSR|S_IWUSR, DB_HASH, NULL);
	if (!db) {
		syslog(LOG_NOTICE, "%s: %m", VDB);
		exit(1);
	}

	if (interval != -1)
		setinterval(interval);

	if (iflag) {
		(void)(db->close)(db);
		exit(0);
	}

	if (!(cur = malloc((u_int)sizeof(ALIAS))))
		exit(1);
	cur->name = pw->pw_name;
	cur->next = names;
	names = cur;

	readheaders();
	if (!recent()) {
		setreply();
		(void)(db->close)(db);
		sendmessage(pw->pw_name);
	} else
		(void)(db->close)(db);
	exit(0);
	/* NOTREACHED */
}
Example #6
0
/*===========================================================================*
 *				do_fork					     *
 *===========================================================================*/
PUBLIC int do_fork()
{
/* The process pointed to by 'mp' has forked.  Create a child process. */

  register struct mproc *rmp;	/* pointer to parent */
  register struct mproc *rmc;	/* pointer to child */
  int i, child_nr, t;
  phys_clicks prog_clicks, child_base;
  phys_bytes prog_bytes, parent_abs, child_abs;	/* Intel only */

 /* If tables might fill up during FORK, don't even start since recovery half
  * way through is such a nuisance.
  */
  rmp = mp;
  if (procs_in_use == NR_PROCS) return(EAGAIN);
  if (procs_in_use >= NR_PROCS-LAST_FEW && rmp->mp_effuid != 0)return(EAGAIN);

  /* Determine how much memory to allocate.  Only the data and stack need to
   * be copied, because the text segment is either shared or of zero length.
   */
  prog_clicks = (phys_clicks) rmp->mp_seg[S].mem_len;
  prog_clicks += (rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
  prog_bytes = (phys_bytes) prog_clicks << CLICK_SHIFT;
  if ( (child_base = alloc_mem(prog_clicks)) == NO_MEM) return(ENOMEM);

  /* Create a copy of the parent's core image for the child. */
  child_abs = (phys_bytes) child_base << CLICK_SHIFT;
  parent_abs = (phys_bytes) rmp->mp_seg[D].mem_phys << CLICK_SHIFT;
  i = sys_copy(ABS, 0, parent_abs, ABS, 0, child_abs, prog_bytes);
  if (i < 0) panic("do_fork can't copy", i);

  /* Find a slot in 'mproc' for the child process.  A slot must exist. */
  for (rmc = &mproc[0]; rmc < &mproc[NR_PROCS]; rmc++)
	if ( (rmc->mp_flags & IN_USE) == 0) break;

  /* Set up the child and its memory map; copy its 'mproc' slot from parent. */
  child_nr = (int)(rmc - mproc);	/* slot number of the child */
  procs_in_use++;
  *rmc = *rmp;			/* copy parent's process slot to child's */

  rmc->mp_parent = who;			/* record child's parent */
  rmc->mp_flags &= (IN_USE|SEPARATE);	/* inherit only these flags */

  /* A separate I&D child keeps the parents text segment.  The data and stack
   * segments must refer to the new copy.
   */
  if (!(rmc->mp_flags & SEPARATE)) rmc->mp_seg[T].mem_phys = child_base;
  rmc->mp_seg[D].mem_phys = child_base;
  rmc->mp_seg[S].mem_phys = rmc->mp_seg[D].mem_phys + 
			(rmp->mp_seg[S].mem_vir - rmp->mp_seg[D].mem_vir);
  rmc->mp_exitstatus = 0;
  rmc->mp_sigstatus = 0;

  /* Find a free pid for the child and put it in the table. */
  do {
	t = 0;			/* 't' = 0 means pid still free */
	next_pid = (next_pid < 30000 ? next_pid + 1 : INIT_PID + 1);
	for (rmp = &mproc[0]; rmp < &mproc[NR_PROCS]; rmp++)
		if (rmp->mp_pid == next_pid || rmp->mp_procgrp == next_pid) {
			t = 1;
			break;
		}
	rmc->mp_pid = next_pid;	/* assign pid to child */
  } while (t);

  /* Tell kernel and file system about the (now successful) FORK. */
  sys_fork(who, child_nr, rmc->mp_pid);
  tell_fs(FORK, who, child_nr, rmc->mp_pid);

  /* Report child's memory map to kernel. */
  sys_newmap(child_nr, rmc->mp_seg);

  /* Reply to child to wake it up. */
  setreply(child_nr, 0);
  return(next_pid);		 /* child's pid */
}
Example #7
0
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
PUBLIC int main()
{
/* Main routine of the process manager. */
  int result, s, proc_nr;
  struct mproc *rmp;
  sigset_t sigset;

  pm_init();			/* initialize process manager tables */

  /* This is PM's main loop-  get work and do it, forever and forever. */
  while (TRUE) {
	get_work();		/* wait for an PM system call */

	/* Check for system notifications first. Special cases. */
	switch(call_nr)
	{
	case SYN_ALARM:
		pm_expire_timers(m_in.NOTIFY_TIMESTAMP);
		result = SUSPEND;		/* don't reply */
		break;
	case SYS_SIG:				/* signals pending */
		sigset = m_in.NOTIFY_ARG;
		if (sigismember(&sigset, SIGKSIG))  {
			(void) ksig_pending();
		} 
		result = SUSPEND;		/* don't reply */
		break;
	case PM_GET_WORK:
		if (who_e == FS_PROC_NR)
		{
			send_work();
			result= SUSPEND;		/* don't reply */
		}
		else
			result= ENOSYS;
		break;
	case PM_EXIT_REPLY:
	case PM_REBOOT_REPLY:
	case PM_EXEC_REPLY:
	case PM_CORE_REPLY:
	case PM_EXIT_REPLY_TR:
		if (who_e == FS_PROC_NR)
		{
			handle_fs_reply(&m_in);
			result= SUSPEND;		/* don't reply */
		}
		else
			result= ENOSYS;
		break;
	case ALLOCMEM:
		result= do_allocmem();
		break;
	case FORK_NB:
		result= do_fork_nb();
		break;
	case EXEC_NEWMEM:
		result= exec_newmem();
		break;
	case EXEC_RESTART:
		result= do_execrestart();
		break;
	case PROCSTAT:
		result= do_procstat();
		break;
	case GETPROCNR:
		result= do_getprocnr();
		break;
	case GETPUID:
		result= do_getpuid();
		break;
	case DIAG_REPL :
		diag_repl();
		result= SUSPEND;
		break;
	default:
		/* Else, if the system call number is valid, perform the
		 * call.
		 */
		if ((unsigned) call_nr >= NCALLS) {
			result = ENOSYS;
		} else {
#if ENABLE_SYSCALL_STATS
			calls_stats[call_nr]++;
#endif

			result = (*call_vec[call_nr])();

		}
		break;
	}

	/* Send the results back to the user to indicate completion. */
	if (result != SUSPEND) setreply(who_p, result);

	/* Send out all pending reply messages, including the answer to
	 * the call just made above.
	 */
	for (proc_nr=0, rmp=mproc; proc_nr < NR_PROCS; proc_nr++, rmp++) {
		/* In the meantime, the process may have been killed by a
		 * signal (e.g. if a lethal pending signal was unblocked)
		 * without the PM realizing it. If the slot is no longer in
		 * use or just a zombie, don't try to reply.
		 */
		if ((rmp->mp_flags & (REPLY | IN_USE | ZOMBIE)) ==
		   (REPLY | IN_USE)) {
			s=sendnb(rmp->mp_endpoint, &rmp->mp_reply);
			if (s != OK) {
				printf("PM can't reply to %d (%s): %d\n",
					rmp->mp_endpoint, rmp->mp_name, s);
			}
			rmp->mp_flags &= ~REPLY;
		}
	}
  }
  return(OK);
}
Example #8
0
/*===========================================================================*
 *				main					     *
 *===========================================================================*/
PUBLIC int main()
{
/* Main routine of the process manager. */
  int result;

  /* SEF local startup. */
  sef_local_startup();
  sched_init();	/* initialize user-space scheduling */

  /* This is PM's main loop-  get work and do it, forever and forever. */
  while (TRUE) {
	  int ipc_status;

	  /* Wait for the next message and extract useful information from it. */
	  if (sef_receive_status(ANY, &m_in, &ipc_status) != OK)
		  panic("PM sef_receive_status error");
	  who_e = m_in.m_source;	/* who sent the message */
	  if(pm_isokendpt(who_e, &who_p) != OK)
		  panic("PM got message from invalid endpoint: %d", who_e);
	  call_nr = m_in.m_type;	/* system call number */

	  /* Process slot of caller. Misuse PM's own process slot if the kernel is
	   * calling. This can happen in case of synchronous alarms (CLOCK) or or
	   * event like pending kernel signals (SYSTEM).
	   */
	  mp = &mproc[who_p < 0 ? PM_PROC_NR : who_p];
	  if(who_p >= 0 && mp->mp_endpoint != who_e) {
		  panic("PM endpoint number out of sync with source: %d",
				  			mp->mp_endpoint);
	  }

	/* Drop delayed calls from exiting processes. */
	if (mp->mp_flags & EXITING)
		continue;

	/* Check for system notifications first. Special cases. */
	if (is_ipc_notify(ipc_status)) {
		switch(who_p) {
			case CLOCK:
				pm_expire_timers(m_in.NOTIFY_TIMESTAMP);
				result = SUSPEND;	/* don't reply */
				break;
			default :
				result = ENOSYS;
		}

		/* done, send reply and continue */
		if (result != SUSPEND) setreply(who_p, result);
		sendreply();
		continue;
	}

	switch(call_nr)
	{
	case PM_SETUID_REPLY:
	case PM_SETGID_REPLY:
	case PM_SETSID_REPLY:
	case PM_EXEC_REPLY:
	case PM_EXIT_REPLY:
	case PM_CORE_REPLY:
	case PM_FORK_REPLY:
	case PM_SRV_FORK_REPLY:
	case PM_UNPAUSE_REPLY:
	case PM_REBOOT_REPLY:
	case PM_SETGROUPS_REPLY:
		/*?????????????????????????????????????????????????????????????????????*/
		/*?????????????????????????????????????????????????????????????????????*/
		/* Chamando a funcao terminator() para todos os processos finalizados. */
		if ( call_nr==PM_EXIT_REPLY ) terminator( _ENDPOINT_P(m_in.m1_i1));
		/*?????????????????????????????????????????????????????????????????????*/
		/*?????????????????????????????????????????????????????????????????????*/

		if (who_e == FS_PROC_NR)
		{
			handle_fs_reply();
			result= SUSPEND;		/* don't reply */
		}
		else
			result= ENOSYS;
		break;
	default:
		/* Else, if the system call number is valid, perform the
		 * call.
		 */
		if ((unsigned) call_nr >= NCALLS) {
			result = ENOSYS;
		} else {
#if ENABLE_SYSCALL_STATS
			calls_stats[call_nr]++;
#endif

			result = (*call_vec[call_nr])();

		}
		break;
	}

	/* Send reply. */
	if (result != SUSPEND) setreply(who_p, result);
	sendreply();
  }
  return(OK);
}