Exemple #1
0
void *waitevent (void *et)
{
	int r;
	struct event_thread *waiter;

	mlockall(MCL_CURRENT | MCL_FUTURE);

	waiter = (struct event_thread *)et;
	pthread_cleanup_push(signal_waiter, et);

	block_signal(SIGUSR1, NULL);
	block_signal(SIGHUP, NULL);
	while (1) {
		r = waiteventloop(waiter);

		if (r < 0)
			break;

		sleep(r);
	}

	pthread_cleanup_pop(1);
	free_waiter(waiter);
	return NULL;
}
Exemple #2
0
void free_waiter (void *data)
{
    sigset_t old;
    struct event_thread *wp = (struct event_thread *)data;

    /*
     * indicate in mpp that the wp is already freed storage
     */
    block_signal(SIGHUP, &old);
    lock(wp->vecs->lock);

    if (wp->mpp)
        /*
         * be careful, mpp may already be freed -- null if so
         */
        wp->mpp->waiter = NULL;
    else
        /*
        * This is OK condition during shutdown.
        */
        condlog(3, "free_waiter, mpp freed before wp=%p (%s).", wp, wp->mapname);

    unlock(wp->vecs->lock);
    pthread_sigmask(SIG_SETMASK, &old, NULL);

    if (wp->dmt)
        dm_task_destroy(wp->dmt);

    FREE(wp);
}
Exemple #3
0
/* This function is reentrant */
static int handle_signal (Signal_Type *s)
{
   int status = 0;
   int was_blocked;

   (void) block_signal (s->sig, &was_blocked);

   /* At this point, sig is blocked and the handler is about to be called.
    * The pending flag can be safely set to 0 here.
    */
   s->pending = 0;

   if (s->handler != NULL)
     {
	int depth = SLstack_depth ();

	if ((-1 == SLang_start_arg_list ())
	    || (-1 == SLang_push_integer (s->sig))
	    || (-1 == SLang_end_arg_list ())
	    || (-1 == SLexecute_function (s->handler)))
	  status = -1;

	if ((status == 0)
	    && (depth != SLstack_depth ()))
	  {
	     SLang_verror (SL_Application_Error, "The signal handler %s corrupted the stack", s->handler->name);
	     status = -1;
	  }
     }

   if (was_blocked == 0)
     (void) unblock_signal (s->sig);

   return status;
}
void thread_kill()
{
    sigset_t mask;
    ll* temp;
    ll* prev;

    while(thread_count != 0)
    {
        prev = temp = head;
        while(temp != NULL)
        {
            if(cur_thread == &temp->thr)
            {
                block_signal(&mask);
                if(temp == head)
                    head = head->next;
                else
                    prev->next = temp->next;

                thread_count--;
                printf("Thread %d with priority %d is exiting\n", cur_thread->id, cur_thread->prt);
                unblock_signal(&mask);
            }
            prev = temp;
            temp = temp->next;
        }
    }
}
/*
  The gtthread_exit() function is analogous to pthread_exit.
 */
void gtthread_exit(void* retval)
{
  int flag = 0, i = 0;
  //Node to be deleted
  steque_node_t* temp = q->front;
  void* exit_item = steque_front(q);

  block_signal();
  //Setting the canceled flag and return value
  ((node_t*)exit_item) -> returns = retval;
  ((node_t*)exit_item) -> canceled = 1;

  //Check if this is the only executing thread. Exit.
  for (i = 0; (i < q->N); i++) {
  	if(((node_t*)temp -> item) -> canceled == 0){
  		flag = 1 ;
  		break;
  	}
  	temp = temp -> next;
  }
  if(flag == 0){
    steque_destroy(q);
    exit(0);
  }
  unblock_signal();

  raise(SIGVTALRM);
}
void clock_stop(void){
	if (clock_state == TIMER_STOPPED) return;
	block_signal(SIGALRM);
	clock_state = TIMER_STOPPED;
    struct itimerval it_val = {{0,0},{0,0}};
    setitimer(ITIMER_REAL,&it_val,NULL);
	unblock_signal(SIGALRM);
}
Exemple #7
0
//start server
NEINT32 start_server(NEINT32 argc, NEINT8 *argv[])
{
	NEINT32 i ;
	NEINT8 *config_file = NULL;
	struct srv_config readcfg = {0} ;

#ifndef WIN32
	//prctl(PR_SET_DUMPABLE, 1);
#ifdef  HANDLE_UNIX_SIGNAL
	block_signal() ;
#endif 
#endif	
	ne_arg(argc, argv);
	
	if(-1==init_module() ) 
		return -1 ;
	
	//get config file 	
	for (i=1; i<argc-1; i++){
		if(0 == nestrcmp(argv[i],"-f")) {
			config_file = argv[i+1] ;
			break ;
		}
	}

	if(!config_file) {
		neprintf("usage: -f config-file\n press ANY key to continue\n") ;
		getch() ;
		exit(1) ;
		//return -1 ;
	}
	__config_file = config_file ;
	if(-1==read_config(config_file, &readcfg) ) {
		neprintf("press ANY key to continue\n") ;
		getch() ;
		exit(1) ;
	}
	//end get config file

	if(-1==init_server_app(&readcfg) ) {
		return -1 ;
	}
	
	return 0;
}
Exemple #8
0
void *run(void *attr){

    block_signal();
    struct request *r = (struct request *)attr;
    struct node *temp = HEAD;

    while(1){
        while(temp->next!=NULL){
             char buff[100];
             sprintf(buff, "%d", temp->data);
             printf("Sending %s\n", buff);
             send(r->sock, buff, 100, 0);
             temp=temp->next;
             sleep(2);
        }
    }

}
Exemple #9
0
void  SIGINT_handler(int sig)
{
    
     block_signal(sig);
     int i;
     pthread_t thread;
//     signal(sig, SIG_IGN);
     printf("From SIGINT: just got a %d (SIGUSR1) signal\n", sig);
     
     for(i=0;message_box->client[i]!=0;i++);
     printf("Creating Thread for - Client with PID %d, Index: %d\n",(int)message_box->client[i-1],i-1);     
//   signal(sig, SIGINT_handler);

     pthread_create(&thread,NULL,server_thread,(void*) (i-1));
     pthread_detach(thread);

     unblock_signal(sig);
}
void alarm_handler(int sig)
{
  void* current = (node_t*)malloc(sizeof(node_t));
  void* next = (node_t*)malloc(sizeof(node_t));

  block_signal();
  current = steque_front(q);

  steque_cycle(q);
  while(1) {
    next = steque_front(q);
    if((((node_t*)next)->canceled) == 0){
      break;
    }
    steque_cycle(q);
  }

  set_alarm();  
  
  swapcontext (((node_t*)current)->thread_ctx, ((node_t*)next)->thread_ctx);
  unblock_signal();
}
void commit_comes(int sessionfd, const char* msg, int RW){
	long pageaddr = *(long*)msg;
	block_signal(SIGALRM);
	// printf(" invalidation responce at %lx\n", pageaddr);
	q_dta_t* the_queue = &req_queues[addr_to_pagenum (dsm_heaptop, pageaddr, dsm_pagesize)];
	if (RW == QUEUE_WRITE){
		memcpy((void*)pageaddr, msg + sizeof(long), dsm_pagesize);
		assert(the_queue->update_pending);

		if (the_queue->listlen){
			if (the_queue->num_parallel_readers){
				for (int i = 0;i < the_queue->num_parallel_readers;i++){
					int posval = the_queue->fd_queue[(i + the_queue->currhead) % (2*NumNode)];
					dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pageaddr,ABS(posval));
				}
			}else{
					dsm_send(0, dsm_pagesize, SERVER_PAGE, (char*)pageaddr, ABS(queue_top(the_queue)));		
			}
		}
	}	
	the_queue->update_pending = 0;
	unblock_signal(SIGALRM);
}
/*
  The gtthread_cancel() function is analogous to pthread_cancel,
  allowing one thread to terminate another asynchronously.
 */
int  gtthread_cancel(gtthread_t thread){
  int i = 0;
  steque_node_t* current = q->front;
  block_signal();
  if (gtthread_equal(thread, gtthread_self())){
    gtthread_exit((void*)GTTHREAD_CANCELED);
  }
  for (i = 0; (i < q->N); i++) {
    if(gtthread_equal(thread, ((node_t*)current -> item) -> id)) {
      if (((node_t*)current -> item) -> canceled == 1){
        return ESRCH;
      }
      else{
        ((node_t*)current -> item) -> canceled = 1;
        ((node_t*)current -> item) -> returns = (void*)GTTHREAD_CANCELED;
        break;
      }      
    }
    current = current -> next;
  }
  unblock_signal();
  return 0;
}
Exemple #13
0
int eval_line(char *cmdline, int e_flag)
{
    char *_argv[MAXARGS];                         /* _argv for execve(), denoted by underscore to distinguish from main argv array*/
    char buf[MAXLINE];                            /* holds modified command line */
    int background;                               /* should the job run in background or foreground? */
    pid_t pid;                                    /* process id */
    int ret = EXIT_SUCCESS;

    strcpy(buf, cmdline);                         /* buf[] will be modified by parse() */
    /* build the argv array */
    background = parse(buf, _argv);

    if(e_flag > 0)
        Echo(_argv);

    if (_argv[0] == NULL)  /* ignore empty lines */
        { return ret; }

    if (builtin(_argv, process_table) == 1) /* the work is done */
        { return ret; }

    if(background)
    {
        block_signal(SIGINT, 1);
    }

    /* child runs user job */
    if ((pid = fork()) == 0)
    {
        if (execvp(_argv[0], _argv/*, environ*/) == -1)
        {
            printf("%s: execve failed: %s\n", _argv[0], strerror(errno));
            _exit(EXIT_FAILURE);
        }
    }

    if (background && pid != 0)                   /* parent waits for foreground job to terminate */
    {
        printf("background process %d: %s", (int) pid, cmdline);

        // Add to process table:
        int err;
        if( (err = insert_process_table(process_table, pid)) == -1)
        {
            fprintf(stderr, "insert_process_table failed: line %d: %s\n", __LINE__, strerror(errno));
        }

        // Passing 0 unblocks the signal.
        block_signal(SIGINT, 0);
    }
    else
    {
        if (waitpid(pid, &ret, 0) == -1)
        {
            printf("%s: waitpid failed: %s\n", _argv[0], strerror(errno));
            exit(EXIT_FAILURE);
        }
        // If in verbose mode, print out a detailed message:
        if(verbose)
        {
            printf("process %d, completed normally, status %d\n", pid, ret);
        }
    }


    return ret;
}
Exemple #14
0
/*
 * Called to set up the pty.
 * 
 * Returns an error message, or NULL on success.
 *
 * Also places the canonical host name into `realhost'. It must be
 * freed by the caller.
 */
static const char *pty_init(void *frontend, void **backend_handle, Conf *conf,
			    char *host, int port, char **realhost, int nodelay,
			    int keepalive)
{
    int slavefd;
    pid_t pid, pgrp;
#ifndef NOT_X_WINDOWS		       /* for Mac OS X native compilation */
    long windowid;
#endif
    Pty pty;

    if (single_pty) {
	pty = single_pty;
        assert(pty->conf == NULL);
    } else {
	pty = snew(struct pty_tag);
	pty->master_fd = pty->slave_fd = -1;
#ifndef OMIT_UTMP
	pty_stamped_utmp = FALSE;
#endif
    }

    pty->frontend = frontend;
    *backend_handle = NULL;	       /* we can't sensibly use this, sadly */

    pty->conf = conf_copy(conf);
    pty->term_width = conf_get_int(conf, CONF_width);
    pty->term_height = conf_get_int(conf, CONF_height);

    if (pty->master_fd < 0)
	pty_open_master(pty);

    /*
     * Set the backspace character to be whichever of ^H and ^? is
     * specified by bksp_is_delete.
     */
    {
	struct termios attrs;
	tcgetattr(pty->master_fd, &attrs);
	attrs.c_cc[VERASE] = conf_get_int(conf, CONF_bksp_is_delete)
	    ? '\177' : '\010';
	tcsetattr(pty->master_fd, TCSANOW, &attrs);
    }

#ifndef OMIT_UTMP
    /*
     * Stamp utmp (that is, tell the utmp helper process to do so),
     * or not.
     */
    if (pty_utmp_helper_pipe >= 0) {   /* if it's < 0, we can't anyway */
        if (!conf_get_int(conf, CONF_stamp_utmp)) {
            close(pty_utmp_helper_pipe);   /* just let the child process die */
            pty_utmp_helper_pipe = -1;
        } else {
            char *location = get_x_display(pty->frontend);
            int len = strlen(location)+1, pos = 0;   /* +1 to include NUL */
            while (pos < len) {
                int ret = write(pty_utmp_helper_pipe, location+pos, len - pos);
                if (ret < 0) {
                    perror("pterm: writing to utmp helper process");
                    close(pty_utmp_helper_pipe);   /* arrgh, just give up */
                    pty_utmp_helper_pipe = -1;
                    break;
                }
                pos += ret;
            }
	}
    }
#endif

#ifndef NOT_X_WINDOWS		       /* for Mac OS X native compilation */
    windowid = get_windowid(pty->frontend);
#endif

    /*
     * Fork and execute the command.
     */
    pid = fork();
    if (pid < 0) {
	perror("fork");
	exit(1);
    }

    if (pid == 0) {
	/*
	 * We are the child.
	 */

	slavefd = pty_open_slave(pty);
	if (slavefd < 0) {
	    perror("slave pty: open");
	    _exit(1);
	}

	close(pty->master_fd);
	noncloexec(slavefd);
	dup2(slavefd, 0);
	dup2(slavefd, 1);
	dup2(slavefd, 2);
	close(slavefd);
	setsid();
#ifdef TIOCSCTTY
	ioctl(0, TIOCSCTTY, 1);
#endif
	pgrp = getpid();
	tcsetpgrp(0, pgrp);
	setpgid(pgrp, pgrp);
        {
            int ptyfd = open(pty->name, O_WRONLY, 0);
            if (ptyfd >= 0)
                close(ptyfd);
        }
	setpgid(pgrp, pgrp);
	{
	    char *term_env_var = dupprintf("TERM=%s",
					   conf_get_str(conf, CONF_termtype));
	    putenv(term_env_var);
	    /* We mustn't free term_env_var, as putenv links it into the
	     * environment in place.
	     */
	}
#ifndef NOT_X_WINDOWS		       /* for Mac OS X native compilation */
	{
	    char *windowid_env_var = dupprintf("WINDOWID=%ld", windowid);
	    putenv(windowid_env_var);
	    /* We mustn't free windowid_env_var, as putenv links it into the
	     * environment in place.
	     */
	}
#endif
	{
	    char *key, *val;

	    for (val = conf_get_str_strs(conf, CONF_environmt, NULL, &key);
		 val != NULL;
		 val = conf_get_str_strs(conf, CONF_environmt, key, &key)) {
		char *varval = dupcat(key, "=", val, NULL);
		putenv(varval);
		/*
		 * We must not free varval, since putenv links it
		 * into the environment _in place_. Weird, but
		 * there we go. Memory usage will be rationalised
		 * as soon as we exec anyway.
		 */
	    }
	}

	/*
	 * SIGINT, SIGQUIT and SIGPIPE may have been set to ignored by
	 * our parent, particularly by things like sh -c 'pterm &' and
	 * some window or session managers. SIGCHLD, meanwhile, was
	 * blocked during pt_main() startup. Reverse all this for our
	 * child process.
	 */
	putty_signal(SIGINT, SIG_DFL);
	putty_signal(SIGQUIT, SIG_DFL);
	putty_signal(SIGPIPE, SIG_DFL);
	block_signal(SIGCHLD, 0);
	if (pty_argv) {
            /*
             * Exec the exact argument list we were given.
             */
	    execvp(pty_argv[0], pty_argv);
            /*
             * If that fails, and if we had exactly one argument, pass
             * that argument to $SHELL -c.
             *
             * This arranges that we can _either_ follow 'pterm -e'
             * with a list of argv elements to be fed directly to
             * exec, _or_ with a single argument containing a command
             * to be parsed by a shell (but, in cases of doubt, the
             * former is more reliable).
             *
             * A quick survey of other terminal emulators' -e options
             * (as of Debian squeeze) suggests that:
             *
             *  - xterm supports both modes, more or less like this
             *  - gnome-terminal will only accept a one-string shell command
             *  - Eterm, kterm and rxvt will only accept a list of
             *    argv elements (as did older versions of pterm).
             *
             * It therefore seems important to support both usage
             * modes in order to be a drop-in replacement for either
             * xterm or gnome-terminal, and hence for anyone's
             * plausible uses of the Debian-style alias
             * 'x-terminal-emulator'...
             */
            if (pty_argv[1] == NULL) {
                char *shell = getenv("SHELL");
                if (shell)
                    execl(shell, shell, "-c", pty_argv[0], (void *)NULL);
            }
        } else {
	    char *shell = getenv("SHELL");
	    char *shellname;
	    if (conf_get_int(conf, CONF_login_shell)) {
		char *p = strrchr(shell, '/');
		shellname = snewn(2+strlen(shell), char);
		p = p ? p+1 : shell;
		sprintf(shellname, "-%s", p);
	    } else
		shellname = shell;
	    execl(getenv("SHELL"), shellname, (void *)NULL);
	}
Exemple #15
0
void
HandleSyscalls()
{
	register int	cnt;
	fd_set 			readfds;
	int 			nfds = -1;

	time_t			periodic_interval_len = 20; /* secs, empirically found :) */

	nfds = (RSC_SOCK > CLIENT_LOG ) ? (RSC_SOCK + 1) : (CLIENT_LOG + 1);

	init_user_ids(Proc->owner, NULL);
	set_user_priv();

	dprintf(D_FULLDEBUG, "HandleSyscalls: about to chdir(%s)\n", Proc->iwd);
	if( chdir(Proc->iwd) < 0 ) {
		sprintf( ErrBuf,  "Can't chdir() to \"%s\"! [%s(%d)]", Proc->iwd, 
			strerror(errno), errno );
		HadErr = TRUE;
		return;
	}

	dprintf(D_SYSCALLS, "Shadow: Starting to field syscall requests\n");
	errno = 0;

	time_t current_time = time(0);
	time_t next_periodic_update = current_time + periodic_interval_len;
	
	for(;;) {	/* get a request and fulfill it */

		FD_ZERO(&readfds);
		FD_SET(RSC_SOCK, &readfds);
		FD_SET(CLIENT_LOG, &readfds);

		struct timeval *ptimer = NULL, timer;
		timer.tv_sec = next_periodic_update - current_time;
		timer.tv_usec = 0;
		ptimer = &timer;
		/* if the current timer is set for a time longer than this, than
			truncate the timer required to the periodic limit. After 
			inspection of the bandwidth timer, it seems that it will recorrect
			itself if select comes out of the loop before the timer goes off
			anyway to handle syscalls */
		if ( timer.tv_sec > periodic_interval_len) {
			timer.tv_sec = next_periodic_update - current_time;
			ptimer = &timer;
		}

		unblock_signal(SIGCHLD);
		unblock_signal(SIGUSR1);
#if defined(LINUX) || defined(Solaris)
		cnt = select(nfds, &readfds, (fd_set *)0, (fd_set *)0, ptimer);
#else
		cnt = select(nfds, &readfds, 0, 0, ptimer);
#endif
		block_signal(SIGCHLD);
		block_signal(SIGUSR1);

		if( cnt < 0 && errno != EINTR ) {
			EXCEPT("HandleSyscalls: select: errno=%d, rsc_sock=%d, client_log=%d",errno,RSC_SOCK,CLIENT_LOG);
		}

		if( cnt < 0 && errno == EINTR ) {
			continue;
		}

		if( FD_ISSET(CLIENT_LOG, &readfds) ) {
			if( HandleLog() < 0 ) {
				EXCEPT( "Peer went away" );
			}
		}

		if( FD_ISSET(RSC_SOCK, &readfds) ) {
			if( do_REMOTE_syscall() < 0 ) {
				dprintf(D_SYSCALLS,
						"Shadow: do_REMOTE_syscall returned < 0\n");
				break;
			}
		}

		if( FD_ISSET(UMBILICAL, &readfds) ) {
			dprintf(D_ALWAYS,
				"Shadow: Local scheduler apparently died, so I die too\n");
			exit(1);
		}

		current_time = time(0);

		/* if this is true, then do the periodic_interval_len events */
		if (current_time >= next_periodic_update) {
			next_periodic_update = current_time + periodic_interval_len;

			/* evaluate some attributes for policies like determining what to
			do if a job suspends wierdly or some such thing. This function
			has the possibility of making the shadow exit with JOB_SHOULD_HOLD
			or futzing up some global variables about how the job could've
			exited and letting Wraup take care of it. */
			if (periodic_policy() == true)
			{
				break;
			}
		}

#if defined(SYSCALL_DEBUG)
		strcpy( SyscallLabel, "shadow" );
#endif
	}

	/*
	The user job might exit while there is still unread data in the log.
	So, select with a timeout of zero, and flush everything from the log.
	*/
		/* 
		   NOTE: Since HandleLog does it's own loop to make sure it's
		   read everything, we don't need a loop here, and should only
		   call HandleLog once.  In fact, if there's a problem w/
		   select(), a loop here can cause an infinite loop.  
		   -Derek Wright and Jim Basney, 2/17/99.
		*/
	HandleLog();
	
		/* Take back normal condor privileges */
	set_condor_priv();

		/* If we are debugging with named pipes as our communications medium,
		   won't have a condor_startd running - don't try to send to it.
		*/
	if( !UsePipes ) {
		send_quit( ExecutingHost, GlobalCap );
	}

	dprintf(D_ALWAYS,
		"Shadow: Job %d.%d exited, termsig = %d, coredump = %d, retcode = %d\n",
			Proc->id.cluster, Proc->id.proc, WTERMSIG(JobStatus),
			WCOREDUMP(JobStatus), WEXITSTATUS(JobStatus));
}
Exemple #16
0
/*ARGSUSED*/
int
main(int argc, char *argv[] )
{
	char	*tmp = NULL;
	int		reserved_swap, free_swap;
	char	*host = NULL, *cluster = NULL, *proc = NULL;
	char	*bogus_capability;
	int		i;

	set_mySubSystem( "SHADOW", SUBSYSTEM_TYPE_SHADOW );

	myDistro->Init( argc, argv );
	if( argc == 2 && strncasecmp(argv[1], "-cl", 3) == MATCH ) {
		printClassAd();
		exit( 0 );
	}

#if defined(SYSCALL_DEBUG)
	SyscallLabel = argv[0] + 7;
#endif

#if !defined(WIN32)
	install_sig_handler(SIGPIPE, (SIG_HANDLER)SIG_IGN );
#endif

	if( argc > 1 ) {
		if( strcmp("-t",argv[1]) == MATCH ) {
			Termlog = 1;
			argv++;
			argc--;
		}
	}

	ShadowBDate = LastRestartTime = time(0);

	_EXCEPT_Cleanup = ExceptCleanup;

	MyPid = getpid();
	
	config();

	/* Start up with condor.condor privileges. */
	/*
	  we need to do this AFTER we call config() so that if CONDOR_IDS
	  is being defined in the config file, we'll get the right value
	*/ 
	set_condor_priv();

	if(Termlog)
		dprintf_set_tool_debug(get_mySubSystem()->getName(), 0);
	else
		dprintf_config( get_mySubSystem()->getName() );
	DebugId = whoami;

	// create a database connection object
	
	dprintf( D_ALWAYS, "******* Standard Shadow starting up *******\n" );
	dprintf( D_ALWAYS, "** %s\n", CondorVersion() );
	dprintf( D_ALWAYS, "** %s\n", CondorPlatform() );
	dprintf( D_ALWAYS, "*******************************************\n" );

	reserved_swap = param_integer("RESERVED_SWAP", 0);
	reserved_swap *= 1024; /* megabytes -> kb */

	bool use_sql_log = param_boolean("QUILL_USE_SQL_LOG", false);
    FILEObj = FILESQL::createInstance(use_sql_log);
	
	free_swap = sysapi_swap_space();

	dprintf( D_FULLDEBUG, "*** Reserved Swap = %d\n", reserved_swap );
	dprintf( D_FULLDEBUG, "*** Free Swap = %d\n", free_swap );
	if( reserved_swap && free_swap < reserved_swap ) {
		dprintf( D_ALWAYS, "Not enough reserved swap space\n" );
		if(FILEObj) {
		  delete FILEObj;
		}

		exit( JOB_NO_MEM );
	}

	dprintf(D_ALWAYS, "uid=%d, euid=%d, gid=%d, egid=%d\n",
		getuid(), geteuid(), getgid(), getegid());

    dprintf(D_FULLDEBUG, "argc = %d\n", argc);
    for(i = 0; i < argc; i++)
    {
        dprintf(D_FULLDEBUG, "argv[%d] = %s\n", i, argv[i]);
    }
	if( argc < 6 ) {
		usage();
	}

	if (param_boolean("SHADOW_DEBUG_WAIT", false, false)) {
		int debug_wait = 1;
		dprintf(D_ALWAYS,
				"SHADOW_DEBUG_WAIT is TRUE, waiting for debugger to attach to pid %d.\n", 
				(int)::getpid());
		while (debug_wait) {
			sleep(1);
		}
	}

	CheckSpoolVersion(SPOOL_MIN_VERSION_SHADOW_SUPPORTS,SPOOL_CUR_VERSION_SHADOW_SUPPORTS);

	if( strcmp("-pipe",argv[1]) == 0 ) {
		bogus_capability = argv[2];
		cluster = argv[3];
		proc = argv[4];
		// read the big comment in the function for why this is here.
		RemoveNewShadowDroppings(cluster, proc);
		pipe_setup( cluster, proc, bogus_capability );
	} else {
		schedd = argv[1];
		host = argv[2];
		bogus_capability = argv[3];
		cluster = argv[4];
		proc = argv[5];
		if ( argc > 6 ) {
			IpcFile = argv[6];
			dprintf(D_FULLDEBUG,"Setting IpcFile to %s\n",IpcFile);
		} else {
			IpcFile = NULL;
		}
		// read the big comment in the function for why this is here.
		RemoveNewShadowDroppings(cluster, proc);
		regular_setup( host, cluster, proc );
	}
	scheddName = getenv( EnvGetName( ENV_SCHEDD_NAME ) );

#if 0
		/* Don't want to share log file lock between child and pnarent */
	(void)close( LockFd );
	LockFd = -1;
#endif

	// initialize the user log
	initializeUserLog();

	My_Filesystem_Domain = param( "FILESYSTEM_DOMAIN" ); 
	dprintf( D_ALWAYS, "My_Filesystem_Domain = \"%s\"\n", 
			 My_Filesystem_Domain );

	My_UID_Domain = param( "UID_DOMAIN" ); 
	dprintf( D_ALWAYS, "My_UID_Domain = \"%s\"\n", My_UID_Domain );

	UseAFS = param_boolean_crufty( "USE_AFS", false ) ? TRUE : FALSE;

	UseNFS = param_boolean_crufty( "USE_NFS", false ) ? TRUE : FALSE;

	// if job specifies a checkpoint server host, this overrides
	// the config file parameters
	tmp = NULL;
	if (JobAd->LookupString(ATTR_CKPT_SERVER, &tmp) == 1) {
		if (CkptServerHost) free(CkptServerHost);
		UseCkptServer = TRUE;
		CkptServerHost = strdup(tmp);
		StarterChoosesCkptServer = FALSE;
		free(tmp);
	} else {
		free(tmp);
		if (CkptServerHost) {
            free(CkptServerHost);
        }
		CkptServerHost = param( "CKPT_SERVER_HOST" );
		UseCkptServer = FALSE;
		if( CkptServerHost && param_boolean_crufty( "USE_CKPT_SERVER", true ) ) {
			UseCkptServer = TRUE;
		}

		StarterChoosesCkptServer =
			param_boolean_crufty("STARTER_CHOOSES_CKPT_SERVER", true) ? TRUE : FALSE;
	}

		// Initialize location of our checkpoint file.  If we stored it
		// on a checkpoint server then set LastCkptServer.  Otherwise,
		// LastCkptServer should be NULL to indicate that we should
		// look on the local disk for our checkpoint file.
	LastCkptServer = NULL;
	if (JobAd->LookupString(ATTR_LAST_CKPT_SERVER,
							&LastCkptServer) == 0) {
		free(LastCkptServer);
		LastCkptServer = NULL;
	}

	// LIGO
	if (param_boolean("ALWAYS_USE_LOCAL_CKPT_SERVER", false)) {
		if (LastCkptServer) {
			char *remoteHost = NULL;
			JobAd->LookupString(ATTR_REMOTE_HOST, &remoteHost);

			char *machineName = strrchr(remoteHost, '@');
			if (machineName == NULL) {
				machineName = remoteHost;
			} else {
				machineName++;
			}

			LastCkptServer = strdup(machineName);
			CkptServerHost = strdup(machineName);

			dprintf(D_ALWAYS, "ALWAYS_USE_LOCAL_CKPT_SERVER is true, forcing LastCkptServer to %s\n", LastCkptServer);
		} else {
			dprintf(D_ALWAYS, "ALWAYS_USE_LOCAL_CKPT_SERVER is true, but checkpoint is not on server, restoring file local file\n");
		}
	}

	MaxDiscardedRunTime = param_integer( "MAX_DISCARDED_RUN_TIME", 3600 );

	CompressPeriodicCkpt = param_boolean( "COMPRESS_PERIODIC_CKPT", false );

	PeriodicSync = param_boolean( "PERIODIC_MEMORY_SYNC", false );

	CompressVacateCkpt = param_boolean( "COMPRESS_VACATE_CKPT", false );

	SlowCkptSpeed = param_integer( "SLOW_CKPT_SPEED", 0 );

	// Install signal handlers such that all signals are blocked when inside
	// the handler.
	sigset_t fullset;
	sigfillset(&fullset);
	install_sig_handler_with_mask( SIGCHLD,&fullset, reaper );

		// SIGUSR1 is sent by the schedd when a job is removed with
		// condor_rm.
	install_sig_handler_with_mask( SIGUSR1, &fullset, handle_sigusr1 );

		// SIGQUIT is sent for a fast shutdow.
	install_sig_handler_with_mask( SIGQUIT, &fullset, handle_sigquit );

		// SIGTERM is sent for a graceful shutdow.
	install_sig_handler_with_mask( SIGTERM, &fullset, handle_sigterm );


	/* Here we block the async signals.  We do this mainly because on HPUX,
	 * XDR wigs out if it is interrupted by a signal.  We do it on all
	 * platforms because it seems like a safe idea.  We unblock the signals
	 * during before select(), which is where we spend most of our time. */
	block_signal(SIGCHLD);
	block_signal(SIGUSR1);      

	/* If the completed job had been committed to the job queue,
		but for some reason the shadow exited wierdly and the
		schedd is trying to run it again, then simply write
		the job termination events and send the email as if the job had
		just ended. */
	if (terminate_is_pending() == TRUE) {
		/* This function will exit()! */
		handle_terminate_pending();
	}

	HandleSyscalls();

	Wrapup();

	/* HACK! WHOOO!!!!! Throw the old shadow away already! */
	/* This will figure out whether or not the job should go on hold AFTER the
		job has exited for whatever reason, or if the job should be allowed
		to exit. It modifies ExitReason approriately for job holding, or, get
		this, just EXCEPTs if the jobs is supposed to go into idle state and
		not leave. :) */
	/* Small change by Todd : only check the static policy if the job really
	   exited of its own accord -- we don't want to even evaluate the static
	   policy if the job exited because it was preempted, for instance */
	if (check_static_policy && 
		(ExitReason == JOB_EXITED || ExitReason == JOB_KILLED 
		     	|| ExitReason == JOB_COREDUMPED)) 
	{
		static_policy();
	}
    if( My_UID_Domain ) {
        free( My_UID_Domain );
    }
    if( My_Filesystem_Domain ) {
        free( My_Filesystem_Domain );
    }
        if(FILEObj) {
                delete FILEObj;
        }

	dprintf( D_ALWAYS, "********** Shadow Exiting(%d) **********\n",
		ExitReason );
	exit( ExitReason );
}
void queue_for_page(int sessionfd, long pagenum, int RW){
    block_signal(SIGALRM);
    
    q_dta_t* the_queue = &(req_queues[pagenum]);
	assert(the_queue->num_parallel_readers <= the_queue->listlen);
	int make_active = 0;
	qaddr = pagenum_to_addr(dsm_heaptop, pagenum, dsm_pagesize);	
	add_to_queue(RW*sessionfd, the_queue);

    if (RW == QUEUE_READ){
        switch (the_queue->q_state){
            case QUEUE_EMPTY:
            {
				int found;
				curr_owners[pagenum] = (short)(long)hash_get((void*)(long)sessionfd, sessionfd_to_nid,&found);
			
				assert(found);	
				the_queue->q_state = QUEUE_READERS;
				if (!the_queue->update_pending){
					long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize); 
					dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd);
				}	
				the_queue->num_parallel_readers = 1;
				break;
            }
            case QUEUE_WRITERS:
			{
				break;
            }
            case QUEUE_READERS:
            {
				if (!the_queue->update_pending){
					long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize);
					dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd);
					
				}
				the_queue->num_parallel_readers++;
				break;
            }
            default:break;
        }
    }else{
		the_queue->num_writers ++;
		switch (the_queue->q_state){
            case QUEUE_EMPTY:
            {
			
				int found;
				curr_owners[pagenum] = (short)(long)hash_get((void*)(long)sessionfd, sessionfd_to_nid,&found);
					
				assert(found);	
				the_queue->q_state = QUEUE_WRITERS;
				make_active = 1;
				if (!the_queue->update_pending){
					long pagebegin = pagenum_to_addr(dsm_heaptop,pagenum, dsm_pagesize);
					dsm_send(0,dsm_pagesize,SERVER_PAGE,(char*)pagebegin,sessionfd);
				}
				break;
            }
            case QUEUE_WRITERS:
			{		
				break;
            }
            case QUEUE_READERS:
            {
				the_queue->q_state = QUEUE_WRITERS;
				make_active = 1;
				break;
            }
            default:break;
        }
    }
	
	if (make_active){
		req_queues[pagenum].next_active = activehead;
		activehead = pagenum;
		clock_start();
	}
    unblock_signal(SIGALRM);
}
Exemple #18
0
/*
 * Called to set up the pty.
 * 
 * Returns an error message, or NULL on success.
 *
 * Also places the canonical host name into `realhost'. It must be
 * freed by the caller.
 */
static const char *pty_init(void *frontend, void **backend_handle, Config *cfg,
			    char *host, int port, char **realhost, int nodelay,
			    int keepalive)
{
    int slavefd;
    pid_t pid, pgrp;
#ifndef NOT_X_WINDOWS		       /* for Mac OS X native compilation */
    long windowid;
#endif
    Pty pty;

    if (single_pty) {
	pty = single_pty;
    } else {
	pty = snew(struct pty_tag);
	pty->master_fd = pty->slave_fd = -1;
#ifndef OMIT_UTMP
	pty_stamped_utmp = FALSE;
#endif
    }

    pty->frontend = frontend;
    *backend_handle = NULL;	       /* we can't sensibly use this, sadly */

    pty->cfg = *cfg;		       /* structure copy */
    pty->term_width = cfg->width;
    pty->term_height = cfg->height;

    if (pty->master_fd < 0)
	pty_open_master(pty);

    /*
     * Set the backspace character to be whichever of ^H and ^? is
     * specified by bksp_is_delete.
     */
    {
	struct termios attrs;
	tcgetattr(pty->master_fd, &attrs);
	attrs.c_cc[VERASE] = cfg->bksp_is_delete ? '\177' : '\010';
	tcsetattr(pty->master_fd, TCSANOW, &attrs);
    }

#ifndef OMIT_UTMP
    /*
     * Stamp utmp (that is, tell the utmp helper process to do so),
     * or not.
     */
    if (!cfg->stamp_utmp) {
	close(pty_utmp_helper_pipe);   /* just let the child process die */
	pty_utmp_helper_pipe = -1;
    } else {
	char *location = get_x_display(pty->frontend);
	int len = strlen(location)+1, pos = 0;   /* +1 to include NUL */
	while (pos < len) {
	    int ret = write(pty_utmp_helper_pipe, location+pos, len - pos);
	    if (ret < 0) {
		perror("pterm: writing to utmp helper process");
		close(pty_utmp_helper_pipe);   /* arrgh, just give up */
		pty_utmp_helper_pipe = -1;
		break;
	    }
	    pos += ret;
	}
    }
#endif

#ifndef NOT_X_WINDOWS		       /* for Mac OS X native compilation */
    windowid = get_windowid(pty->frontend);
#endif

    /*
     * Fork and execute the command.
     */
    pid = fork();
    if (pid < 0) {
	perror("fork");
	exit(1);
    }

    if (pid == 0) {
	/*
	 * We are the child.
	 */

	slavefd = pty_open_slave(pty);
	if (slavefd < 0) {
	    perror("slave pty: open");
	    _exit(1);
	}

	close(pty->master_fd);
	fcntl(slavefd, F_SETFD, 0);    /* don't close on exec */
	dup2(slavefd, 0);
	dup2(slavefd, 1);
	dup2(slavefd, 2);
	close(slavefd);
	setsid();
#ifdef TIOCSCTTY
	ioctl(0, TIOCSCTTY, 1);
#endif
	pgrp = getpid();
	tcsetpgrp(0, pgrp);
	setpgid(pgrp, pgrp);
	close(open(pty->name, O_WRONLY, 0));
	setpgid(pgrp, pgrp);
	{
	    char *term_env_var = dupprintf("TERM=%s", cfg->termtype);
	    putenv(term_env_var);
	    /* We mustn't free term_env_var, as putenv links it into the
	     * environment in place.
	     */
	}
#ifndef NOT_X_WINDOWS		       /* for Mac OS X native compilation */
	{
	    char *windowid_env_var = dupprintf("WINDOWID=%ld", windowid);
	    putenv(windowid_env_var);
	    /* We mustn't free windowid_env_var, as putenv links it into the
	     * environment in place.
	     */
	}
#endif
	{
	    char *e = cfg->environmt;
	    char *var, *varend, *val, *varval;
	    while (*e) {
		var = e;
		while (*e && *e != '\t') e++;
		varend = e;
		if (*e == '\t') e++;
		val = e;
		while (*e) e++;
		e++;

		varval = dupprintf("%.*s=%s", varend-var, var, val);
		putenv(varval);
		/*
		 * We must not free varval, since putenv links it
		 * into the environment _in place_. Weird, but
		 * there we go. Memory usage will be rationalised
		 * as soon as we exec anyway.
		 */
	    }
	}

	/*
	 * SIGINT, SIGQUIT and SIGPIPE may have been set to ignored by
	 * our parent, particularly by things like sh -c 'pterm &' and
	 * some window or session managers. SIGCHLD, meanwhile, was
	 * blocked during pt_main() startup. Reverse all this for our
	 * child process.
	 */
	putty_signal(SIGINT, SIG_DFL);
	putty_signal(SIGQUIT, SIG_DFL);
	putty_signal(SIGPIPE, SIG_DFL);
	block_signal(SIGCHLD, 0);
	if (pty_argv)
	    execvp(pty_argv[0], pty_argv);
	else {
	    char *shell = getenv("SHELL");
	    char *shellname;
	    if (cfg->login_shell) {
		char *p = strrchr(shell, '/');
		shellname = snewn(2+strlen(shell), char);
		p = p ? p+1 : shell;
		sprintf(shellname, "-%s", p);
	    } else
Exemple #19
0
int main(int argc, char *argv[])
{
    /* Packet Thread */
    /* Initialize the mutex */
    pthread_mutex_init(&m, 0);

    int i;
    char *lambda = "0.5";
    char *mu = "0.35";
    char *r = "1.5";
    char *B = "10";
    char *P = "3";
    char *n = "20";
    char *FILENAME = NULL;
    AVAILABLE = 0;
    DROPPED = 0;
    DROPPED_PKT = 0;
    TOTAL = 0;
    TOTAL_SERVED = 0;
    SERVER_DIE = 0;

    /* Read Options */
    for(i=1;i<argc;i=i+2){
        if (i%2!=0 && argv[i][0]=='-'){
            if ((strcmp(argv[i]+1, "lambda") == 0) && ((i+1)<argc)){
                lambda = argv[i+1];
                if(check_num(lambda)== -1){
                    fprintf(stderr, "Value of lambda is not a number.\n");
                    exit(0);
                }
                continue;
            }
            else if ((strcmp(argv[i]+1, "mu") == 0) && ((i+1)<argc)){
                mu = argv[i+1];
                if(check_num(mu)== -1){
                    fprintf(stderr, "Value of mu is not a number.\n");
                    exit(0);
                }
                continue;
            }
            else if ((strcmp(argv[i]+1, "r") == 0) && ((i+1)<argc)){
                r = argv[i+1];
                if(check_num(r)== -1){
                    fprintf(stderr, "Value of r is not a number.\n");
                    exit(0);
                }
                continue;
            }
            else if ((strcmp(argv[i]+1, "B") == 0) && ((i+1)<argc)){
                B = argv[i+1];
                if(isNum(B)==-1){
                    fprintf(stderr, "Value of B is not a number.\n");
                    exit(0);
                }
                continue;
            }
            else if((strcmp(argv[i]+1, "P") == 0) && ((i+1)<argc)){
                P = argv[i+1];
                if(isNum(P) == -1){
                    fprintf(stderr, "Value of P is not a number.\n");
                    exit(0);
                }
                continue;
            }
            else if ((strcmp(argv[i]+1, "n") == 0) && ((i+1)<argc)){
                n = argv[i+1];
                if(isNum(n)==-1){
                    fprintf(stderr, "Value of n is not a number.\n");
                    exit(0);
                }
                continue;
            }
            else if ((strcmp(argv[i]+1, "t") == 0) && ((i+1)<argc)){
                FILENAME = argv[i+1];
                continue;
            }
        }
        fprintf(stderr, "Wrong command line argument\n");
        exit(0);
        break;
     }

    /*Allocate memory to list*/
    Q1 = malloc(sizeof(My402List));
    Q2 = malloc(sizeof(My402List));
    /*Initilialize the list*/
    My402ListInit(Q1);
    My402ListInit(Q2);

    /* Block Signal from Main thread */
    block_signal();

    if(FILENAME!=NULL){
        FILE *fp = fopen(FILENAME, "r");
        if(fp==NULL){
            perror("Error: Unable to open the file ");
            exit(0);
        }
        fclose(fp);
    }

   
    print_input(lambda, mu, FILENAME, r, B, P, n);
    /* Create packet thread */

    fprintf(stdout, "\n");
    /* Initialize the stats */ 
    init_stats();

    struct timeval current = diff_timeval(START_TIMEVAL, PKT_BEFORE);
    fprintf(stdout, "%08llu.%03ldms: emulation begins\n",
            toMilliSeconds(current), current.tv_usec%MILLI);

    /* Create threads */
    create_packet_thread(lambda, mu, FILENAME, r, B, P, n);

    /* Print statistics */
    //print_stats();

    return(0);
}
Exemple #20
0
/*
 * get_child_exit: This looks for dead child processes of the client.
 * There are two main sources of dead children:  Either an /exec'd process
 * has exited, or the client has attempted to fork() off a helper process
 * (such as wserv or gzip) and that process has choked on itself.
 *
 * When SIGCHLD is recieved, the global variable 'dead_children_processes'
 * is incremented.  When this function is called, we go through and call
 * waitpid() on all of the outstanding zombies, conditionally stopping when
 * we reach a specific wanted sub-process.
 *
 * If you want to stop reaping children when a specific subprocess is 
 * reached, specify the process in 'wanted'.  If all youre doing is cleaning
 * up after zombies and /exec's, then 'wanted' should be -1.
 */
int 		get_child_exit (pid_t wanted)
{
	Process	*proc;
	pid_t	pid;
	int	status, i;

	/*
	 * Iterate until we've reaped all of the dead processes
	 * or we've found the one asked for.
	 */
	if (dead_children_processes)
	{
	    block_signal(SIGCHLD);
	    while ((pid = waitpid(wanted, &status, WNOHANG)) > 0)
	    {
		/*
		 * First thing we do is look to see if the process we're
		 * working on is the one that was asked for.  If it is,
		 * then we get its exit status information and return it.
		 */
		if (wanted != -1 && pid == wanted)
		{
			/* 
			 * We do not clear 'dead_children_processes' here
			 * because we do not know if we've reaped all of
			 * the children yet!  Leaving it set means this 
			 * function is called again, and then if there are
			 * no more left, it is cleared (below).
			 */
		        unblock_signal(SIGCHLD);

			if (WIFEXITED(status))
				return WEXITSTATUS(status);
			if (WIFSTOPPED(status))
				return -(WSTOPSIG(status));
			if (WIFSIGNALED(status)) 
				return -(WTERMSIG(status));
		}

		/*
		 * If it wasnt the process asked for, then we've probably
		 * stumbled across a dead /exec'd process.  Look for the
		 * corresponding child process, and mark it as being dead.
		 */
		else
		{
			for (i = 0; i < process_list_size; i++)
			{
				proc = process_list[i];
				if (proc && proc->pid == pid)
				{
					proc->exited = 1;
					proc->termsig = WTERMSIG(status);
					proc->retcode = WEXITSTATUS(status);
					break;
				}
			}
		}
	    }
	    dead_children_processes = 0;
	    unblock_signal(SIGCHLD);
	}

	/*
	 * Now we may have reaped some /exec'd processes that were previously
	 * dumb and have now exited.  So we call cleanup_dead_processes() to 
	 * find and delete any such processes.
	 */
	cleanup_dead_processes();

	/*
	 * If 'wanted' is not -1, then we didnt find that process, and
	 * if 'wanted' is -1, then you should ignore the retval anyhow. ;-)
	 */
	return -1;
}