Пример #1
0
int fork_pipes (int n, struct command *cmd)
{
  int i;
  pid_t pid;
  int in, fd [2];

  /* The first process should get its input from the original file descriptor 0.  */
  in = 0;

  /* Note the loop bound, we spawn here all, but the last stage of the pipeline.  */
  for (i = 0; i < n - 1; ++i)
    {
      pipe (fd);

      /* f [1] is the write end of the pipe, we carry `in` from the prev iteration.  */
      spawn_proc (in, fd [1], cmd + i);

      /* No need for the write end of the pipe, the child will write here.  */
      close (fd [1]);

      /* Keep the read end of the pipe, the next child will read from there.  */
      in = fd [0];
    }

  /* Last stage of the pipeline - set stdin be the read end of the previous pipe
     and output to the original file descriptor 1. */  
  if (in != 0)
    dup2 (in, 0);

  /* Execute the last stage with the current process. */
  return execvp (cmd [i].argv [0], (char * const *)cmd [i].argv);
}
Пример #2
0
int
handle_start_proc(struct request * r)
{
    fprintf(stderr, "starting proc\n");
    struct child_process * c = make_child_proc((struct svc_packet *)r->data);
    if (0 == c)
    {
        fprintf(stderr, "failed to created child process structure\n");
        return -1;
    } 
    else
    {
        if (c->start_calendar_interval)
        {
            struct timeval now;
            gettimeofday(&now, 0); 
            c->last_restart = *(next_start(&now, c->start_calendar_interval));
            queue_proc(c);
        }
        else
        {
            fprintf(stderr, "starting proc %s\n", c->label);
            gettimeofday(&c->last_restart, 0);
            spawn_proc(c);
        }
        return 0;
    }
}
Пример #3
0
/* Helper function that forks pipes */
static void fork_pipes(int n, struct command *cmd)
{
    int i;
    int in = 0;
    int fd[2];
    for (i = 0; i < n - 1; ++i)
    {
        pipe(fd);
        spawn_proc(in, fd[1], cmd + i);
        close(fd[1]);
        in = fd[0];
    }
    if (dup2(in, 0) < 0)	{
        err_syserr("dup2() failed on stdin for %s: ", cmd[i].argv[0]);
    }
    fprintf(stderr, "%d: executing %s\n", (int)getpid(), cmd[i].argv[0]);
    execvp(cmd[i].argv[0], cmd[i].argv);
    err_syserr("failed to execute %s: ", cmd[i].argv[0]);
}
Пример #4
0
int
main(int argc, char * argv[])
{
    int fd;
    struct sigaction sig;
    struct passwd * pwd = 0;
    
    if (argc == 2)
    {
        if (argv[1])
        {
            errno = 0; 
            pwd = getpwnam(argv[1]);
            if (0 == pwd)
            {
                fprintf(stderr, "getpwnam failed: %s\n", strerror(errno));
                while(1)
                {
                    pause();
                }
            }  
        } 
    }
    
    if (pwd)
    {
        sprintf(process_manager_run_dir, "/run/process-manager.%s", pwd->pw_name);
        sprintf(process_manager_socket_path, "/run/process-manager.%s/procman", pwd->pw_name);
    }
    else 
    {
        sprintf(process_manager_run_dir, "/run/process-manager");
        sprintf(process_manager_socket_path, "/run/process-manager/procman");
        we_are_root = 1;
    }
    
    (void)fprintf(stderr, "process-manager: process-manager starting...\n");

    memset(&sig, 0, sizeof(sig));
    sigfillset(&sig.sa_mask);
    sig.sa_flags = SA_SIGINFO;
    sig.sa_sigaction = handle_sigterm;
    sigaction(SIGTERM, &sig, 0);

    memset(&sig, 0, sizeof(sig));
    sigfillset(&sig.sa_mask);
    sig.sa_flags = SA_SIGINFO;
    sig.sa_sigaction = handle_sigchild;
    sigaction(SIGCHLD, &sig, 0);
       
    memset(&sig, 0, sizeof(sig));
    sigfillset(&sig.sa_mask);
    sig.sa_flags = SA_SIGINFO;
    sig.sa_sigaction = handle_sigalarm;
    sigaction(SIGALRM, &sig, 0); 

    fd = open("/dev/console", O_RDWR | O_NOCTTY);
    if (fd >= 0)
    {
        dup2(fd,0); 
        dup2(fd,1);
        dup2(fd,2);
        if (fd > 2)
            close(fd);
        (void)fprintf(stderr, "process-manager: console reopened...\n");
    }
    else
    {
        (void)fprintf(stderr, "failed to open console");
    }     

    if (we_are_root)
    {
        struct stat stat_buf;
        memset(&stat_buf, 0, sizeof(stat_buf));
        
        if (-1 == stat("/run/process-manager", &stat_buf))
        {
            fprintf(stderr, "expected stat error: %s\n", strerror(errno));
            if (-1 == mount("none", "/run", "tmpfs", 0, 0))
            {
                fprintf(stderr, "failed to mount tmpfs on /run: %s\n", strerror(errno));
                while(1)
                    pause();
            }
            fprintf(stderr, "we are root\n");
            if (-1 == mkdir("/run/process-manager", 0770))
            {
                fprintf(stderr, "failed to make dir /run/process-manager: %s\n", strerror(errno));
                while(1)
                    pause();
            }
            struct group * g = getgrnam("process-manager");
            if (g)
            {
                if (-1 == chown("/run/process-manager", -1, g->gr_gid))
                    fprintf(stderr, "chown gid %d failed: %s\n", g->gr_gid, strerror(errno));
                if (-1 == chmod("/run/process-manager", S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP
                    |S_IXGRP))
                    fprintf(stderr, "chmod failed: %s\n", strerror(errno));
            }
            else
            {
                fprintf(stderr, "getgrnam process-manager failed: %s\n", strerror(errno));
            } 
        }
    }
    else
    {
        mkdir(process_manager_run_dir, 0700);
        if (-1 == chown(process_manager_run_dir, pwd->pw_uid, pwd->pw_gid))
            fprintf(stderr, "chown failed: %s\n", strerror(errno));
    } 

    running = malloc(sizeof(*running));
    memset(running, 0, sizeof(*running));
    running->next = running; 

    waiting = malloc(sizeof(*waiting));
    memset(waiting, 0, sizeof(*waiting));
    waiting->next = waiting;
    waiting->pid = 0x7fffffff;
    waiting->last_restart.tv_sec = 0x7fffffffffffffff; 

    inactive = malloc(sizeof(*inactive));
    memset(inactive,0 ,sizeof(*inactive));
    inactive->next = inactive;

    struct sockaddr_un ctl_un;
    pid_t ctl_pid;
    socklen_t ctl_len; 
    int ctl_p_endp = launch_control_proc(pwd, process_manager_socket_path, &ctl_un, &ctl_len, &ctl_pid);

    if (ctl_p_endp < 0) //socket already exists and another instance is running
    {
        fprintf(stderr, "socket in use, ctl_p_endp: %d\n", ctl_p_endp);
        return 1;
    }
  
    if (we_are_root)
        spawn_proc(&arbitrator);

    while(0 == run_state)
    {
        int status;
        pid_t child_pid = -1;
        struct child_process * proc;  
        unsigned char restart_proc = 0; 

        if (waiting->next == waiting)
        {
            alarm(0);
        }
        else
        {
            struct timeval now;
            gettimeofday(&now, 0);
            alarm(waiting->next->last_restart.tv_sec - now.tv_sec); 
        }

        timeout = 0; 

        fprintf(stderr, "waiting for exiting childern...\n");
        unsigned char data[1024];
        unsigned int len = sizeof(data);
        if (-1 == recvfrom(ctl_p_endp, data, len, 0, &ctl_un, &ctl_len))
        {
            if (errno == EINTR)
            {
                fprintf(stderr, "process-manager: signal received: %d, run_state == %d\n", signum, run_state);
                if (timeout)
                {
                    timeout = 0;
                    struct timeval now;
                    gettimeofday(&now, 0);  
                    fprintf(stderr, "we got timeout. next timeout %ld, it is now %ld\n", waiting->next->last_restart.tv_sec,
                        now.tv_sec);
                    while(waiting->next->last_restart.tv_sec <= now.tv_sec)
                    { 
                        struct child_process * c = dequeue_proc();
                        fprintf(stderr, "restarting queued proc %s\n", c->label);
                        spawn_proc(c);
                    }
                }
                if (got_sigchild)
                {
                    got_sigchild = 0;
                    while((child_pid = waitpid(-1, &status, WNOHANG)))
                    {
                        if (child_pid < 0)
                        {
                            fprintf(stderr, "failed to get child status: %s\n", strerror(errno));
                            if (EINTR != errno) break;  
                        }
                        else
                        {
                            proc = get_process(child_pid);
                            child_pid = -1;
                            if (proc)
                            {
                                kill(-proc->pid, SIGTERM);

                                restart_proc = 0;
                                if (proc->start_calendar_interval)
                                {
                                    struct timeval now;
                                    gettimeofday(&now, 0); 
                                    proc->last_restart = *(next_start(&now, proc->start_calendar_interval));
                                    queue_proc(proc);
                                } 
                                else if (proc->keepalive_opts)
                                {
                                    int i = 0;
                                    while(proc->keepalive_opts[i])
                                    {
                                        fprintf(stderr, "keepalive opts %d:%d\n", proc->keepalive_opts[i], 
                                            proc->keepalive_opts[i + 1]);
                                        if (SUCCESSFUL_EXIT == proc->keepalive_opts[i])
                                        {
                                            if (0 <  proc->keepalive_opts[i + 1])
                                            {
                                                if (WIFEXITED(status))
                                                {
                                                    restart_proc |= 1;
                                                }
                                            }
                                            else
                                            {
                                                if (WIFSIGNALED(status))
                                                {
                                                    restart_proc |= 1;
                                                }  
                                            } 
                                        }
                                        i += 2; 
                                    } 
                                }
            
                                if (restart_proc)
                                {
                                    fprintf(stderr, "restarting %s, exec file %s\n", proc->label, proc->exec_file_path);
                                    struct timeval now;
                                    gettimeofday(&now, 0);
                                    fprintf(stderr, "%s last restart %ld it is now %ld\n", 
                                        proc->label, proc->last_restart.tv_sec, now.tv_sec);
                                    if ((proc->last_restart.tv_sec + 10) < now.tv_sec)
                                    {
                                        gettimeofday(&proc->last_restart, 0);
                                        spawn_proc(proc);
                                        fprintf(stderr, "spawn %s pid %d\n", proc->exec_file_path, proc->pid);
                                    }
                                    else
                                    {
                                        if (proc->throttle_count < 40)
                                        {   
                                            fprintf(stderr, "throttling %s\n", proc->label);
                                            gettimeofday(&proc->last_restart, 0);
                                            proc->last_restart.tv_sec += 10;
                                            proc->throttle_count++;
                                            fprintf(stderr, "%s throttle_count %d restart at %ld\n",
                                                 proc->label, proc->throttle_count, proc->last_restart.tv_sec);
                                            queue_proc(proc);
                                        } 
                                        else
                                        {
                                            fprintf(stderr, "%s exceeded throttle limit\n", proc->label);
                                            destroy_proc_struct(proc);
                                        } 
                                    } 
                                }
                                else
                                {
                                    if (WIFEXITED(status))
                                        fprintf(stderr, "process %s:%d %s exited with %d\n", proc->label, proc->pid, proc->exec_file_path, WEXITSTATUS(status));
                                    else if (WIFSIGNALED(status)) 
                                        fprintf(stderr, "process %s:%d signaled with %d\n", proc->label, proc->pid, WTERMSIG(status));
                                    destroy_proc_struct(proc);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                fprintf(stderr, "recvfrom failed: %s\n", strerror(errno));
                sleep(3); 
            }  
        }
        else
        {
            handle_data(data, len);
        }
    }

    unsigned char any_child_exists = 1;
    int status = 0;

    fprintf(stderr, "sending SIGTERM to all children...\n");
    struct child_process * v = running->next;
    while(running != v)
    {
        if (-1 == kill(-v->pid, SIGTERM))
        {
            fprintf(stderr, "process-manager: kill process group %d failed: %s\n", -v->pid, strerror(errno));
            if (-1 == kill(v->pid, SIGTERM))
            {
                fprintf(stderr, "process-manager: kill %d failed: %s\n", v->pid, strerror(errno));
            }
        }
        v = v->next;
    }
    kill(ctl_pid, SIGTERM);

    alarm(5);

    while (any_child_exists)
    {
        pid_t child = wait(&status);
        if (0 > child) 
        {
            if (ECHILD == errno) 
            {
                any_child_exists = 0;
                fprintf(stderr, "process-manager: no more children left...\n");
            }
            else if (EINTR == errno)
            {
                if (timeout)
                {
                    timeout = 0;
                    any_child_exists = 0;
                }
            }
        }   
    }
    alarm(0);

    sleep(1);
 
    close(ctl_p_endp);
    unlink(process_manager_socket_path);
    return 0;
}
Пример #5
0
int executePipe( int no_of_pipes, char *com, int redirectFlag,char *homedir)
{
    pc *pcmd=malloc(100 * sizeof(pc));
    int fd[2];
    int isFirstPipe=1;
    int count = 0;
    char *commandline=malloc(1024*sizeof(char));
    strcpy(commandline,com);

    char *command=malloc(1024*sizeof(char));
    char **argv=malloc ( 100 * sizeof(char)); //Number of tokens there can be
    char *token=malloc(1024*sizeof(char));
    int i=0,j=0;
    command = strtok ( com,"|");  //first command
    while( command!=NULL)
    {
        pcmd[i].argv=command;
        pcmd[i].redirectFlag=isRedirect(command);
        command = strtok (NULL, "|");
        i++;
    }
    //Tokenise command for execution
    //parseCommand(pcmd[0].argv,argv);

    int in=0;
    for(i=0;i<no_of_pipes;i++)
    {
        pipe(fd);
        spawn_proc(in,fd[1],pcmd[i],pcmd[i].redirectFlag,homedir);
        close(fd[1]);
        in=fd[0];
    }
    if(in!=0)
        dup2(in,0);
    //last command
    infile=0;
    outfile=0;
    int random=isRedirect(pcmd[i].argv);
    int no_of_tokens=parseCommand(pcmd[i].argv,argv,pcmd[i].redirectFlag);
    int std_out=dup(1);
    if(outfile!=0)
    {
        int fd1;
        if(outfile==1)
        {
            fd1=open(output,O_CREAT|O_RDWR|O_TRUNC,00666);
            lseek(fd1, 0, SEEK_SET);
        }
        else if(outfile==2)
        {
            fd1=open(output,O_APPEND|O_CREAT|O_RDWR,00666);
        }
        if(fd1==-1)
        {
            fprintf(stderr, "Can't open file for output 1!\n");
            memset(output, 0, 10);
            outfile=0;
            return;
        }
        dup2(fd1,STDOUT_FILENO);
        close(fd1);
        memset(output, 0, 10);
        outfile=0;
        //redirectFlag=0;
    }
    if(infile==3)
    {
        int fd2;
        fd2=open(inputfile,O_RDWR,00666);
        if(fd2==-1)
        {
            fprintf(stderr, "Can't open file for input! 3\n");
            memset(inputfile, 0, 10);
            infile=0;
            return;
        }
        dup2(fd2,STDIN_FILENO);
        close(fd2);
        memset(inputfile, 0, 10);
        infile=0;
        //redirectFlag=0;
    }

    if(isBuiltInCommand(argv[0])==1)
    {
        job_no++;
        addJob(0,argv[0],0,job_no);
        executeBuiltInCommand(argv[0],argv,no_of_tokens,homedir);
        _exit(1);
        dup2(std_out,1);
        return(0);
    }
    else
        return(execvp(argv[0],argv));
}