X-Git-Url: https://git.ucc.asn.au/?p=matches%2Fswarm.git;a=blobdiff_plain;f=src%2Fmaster.c;h=f5e17eb00ce4efee6ba189f8c5f7962ef6e953c5;hp=2734d0772d8d6391d7583114b1b2c36963f5b079;hb=HEAD;hpb=4e2127d6576cea3f54c619d0bb20a22006567206 diff --git a/src/master.c b/src/master.c index 2734d07..f5e17eb 100644 --- a/src/master.c +++ b/src/master.c @@ -2,6 +2,7 @@ #include "master.h" #include "log.h" +#include #include #include "daemon.h" #include @@ -101,7 +102,19 @@ void Master_setup(Options * o) // One slave per CPU for (int i = 0; i < master.nSlaves; ++i) { - Make_slave(i); + + + int sv[2]; + // Possibly the best function ever + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0) + { + error("Make_slave", "Setting up socketpair for slave %d : %s", i, strerror(errno)); + } + master.slave[i].in = sv[1]; + master.slave[i].out = sv[1]; + master.slave[i].socket_child_end = sv[0]; + + Master_shell(i); @@ -114,23 +127,16 @@ void Master_setup(Options * o) } } -void Make_slave(int i) -{ - int sv[2]; - if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) != 0) - { - error("Make_slave", "Setting up socketpair for slave %d : %s", i, strerror(errno)); - } - +void Master_shell(int i) +{ master.slave[i].pid = fork(); if (master.slave[i].pid == 0) { - dup2(sv[0],fileno(stdin)); - dup2(sv[0],fileno(stdout)); + dup2(master.slave[i].socket_child_end,fileno(stdin)); + dup2(master.slave[i].socket_child_end,fileno(stdout)); execlp(master.o->shell, master.o->shell, NULL); } - master.slave[i].in = sv[1]; - master.slave[i].out = sv[1]; + master.slave[i].running = true; } @@ -395,14 +401,19 @@ void Master_output(int i, char c) memset(t->output+(t->outlen), 0, sizeof(char) * t->outsiz - t->outlen); } - if (c == EOF || (master.o->endlen > 0 && t->outlen >= master.o->endlen - && strcmp((t->output)+(t->outlen)-(master.o->endlen), master.o->end) == 0)) + if (c == EOF + #ifdef SHELL_OUTPUT_FINISHED + || (t->outlen >= SHELL_OUTPUT_FINISHED_LENGTH + && strcmp((t->output)+(t->outlen)-(SHELL_OUTPUT_FINISHED_LENGTH), SHELL_OUTPUT_FINISHED) == 0)) + #else + ) // this is totally readable + #endif //SHELL_OUTPUT_FINISHED { if (c != EOF) { - t->output[t->outlen - master.o->endlen] = '\0'; - t->outlen -= master.o->endlen; + t->output[t->outlen - SHELL_OUTPUT_FINISHED_LENGTH] = '\0'; + t->outlen -= SHELL_OUTPUT_FINISHED_LENGTH; } master.slave[i].task = NULL; @@ -571,7 +582,7 @@ void Master_loop() if (errno != ENXIO) error("Master_loop", "Daemon trying to reopen fifo %s : %s", DAEMON_FIFO, strerror(errno)); else - log_print(2, "Master_loop", "Daemon couldn't reopen fifo %s : %s", DAEMON_FIFO, strerror(errno)); + log_print(LOGWARN, "Master_loop", "Daemon couldn't reopen fifo %s : %s", DAEMON_FIFO, strerror(errno)); } else { @@ -670,17 +681,18 @@ void Master_send() write(send_task.slave_fd, master.o->append, (len-1) * sizeof(char)); //log_print(0, "Sent append %s\n",master.o->append); } - if (master.o->end != NULL) + #ifdef SHELL_OUTPUT_FINISHED { static char * echo = ";echo -en \""; static int len = -1; if (len == -1) len = strlen(echo); write(send_task.slave_fd, echo, len*sizeof(char)); - write(send_task.slave_fd, master.o->end, (master.o->endlen) * sizeof(char)); - write(send_task.slave_fd, "\"", 1*sizeof(char)); + write(send_task.slave_fd, SHELL_OUTPUT_FINISHED, SHELL_OUTPUT_FINISHED_LENGTH * sizeof(char)); + write(send_task.slave_fd, "\"", sizeof(char)); //log_print(0, "Sent end\n"); } - write(send_task.slave_fd, "\n", 1*sizeof(char)); + #endif //SHELL_OUTPUT_FINISHED + write(send_task.slave_fd, "\n", sizeof(char)); master.commands_active++; log_print(3, "Master_sender", "Sent task %d \"%s\" on socket %d - %d tasks active", send_task.task->number, send_task.task->message, send_task.slave_fd, master.commands_active); } @@ -741,7 +753,7 @@ void Master_cleanup() { FILE * f = fdopen(master.remote_err[i], "r+"); setbuf(f, NULL); - fprintf(f, "exit\n"); + fprintf(f, SHELL_EXIT_COMMAND); fclose(f); } @@ -750,8 +762,8 @@ void Master_cleanup() { static int exitlen = -1; - if (exitlen == -1) exitlen = strlen(SHELL_EXIT_MESSAGE); - write(master.slave[i].in, SHELL_EXIT_MESSAGE, exitlen *sizeof(char)); + if (exitlen == -1) exitlen = strlen(SHELL_EXIT_COMMAND); + write(master.slave[i].in, SHELL_EXIT_COMMAND, exitlen *sizeof(char)); //usleep(0.5); //shouldn't matter too much } @@ -876,7 +888,11 @@ void Master_absorb(char * addr, int np) } while (buffer[len-1] != '\n'); buffer[len-1] = '\0'; - newSlaves = atoi(buffer); + + while (newSlaves == 0 && strcmp(buffer, "0") != 0) + { + newSlaves = atoi(buffer); + } @@ -986,34 +1002,21 @@ void sigchld_handler(int signal) return; } - fprintf(stderr, "Unexpected exit of slave %s", master.slave[i].name); - if (WIFSIGNALED(s)) - { - int sig = WTERMSIG(s); - fprintf(stderr, " due to %s", strsignal(sig)); - if (sig == SIGKILL) - { - printf(" - committing suicide\n"); - kill(getpid(), sig); - } - } - else - { - fprintf(stderr, " return code %d.",s); - } - fprintf(stderr, " Starting replacement.\n"); - Make_slave(i); + sigchld_respond(s, "local", i); + + Master_shell(i); - if (master.o->end != NULL) + #ifdef SHELL_OUTPUT_FINISHED { //log_print(1, "sigchld_handler", "Trying to convince slave %d to be nice", i); char buffer[BUFSIZ]; - sprintf(buffer, "name=%s;echo -en \"%s\"\n", master.slave[i].name, master.o->end); - if (write(master.slave[i].in, buffer, strlen(buffer)) <= 0) + int len = sprintf(buffer, "name=%s;echo -en \"%s\"\n", master.slave[i].name, SHELL_OUTPUT_FINISHED); + if (write(master.slave[i].in, buffer, len) <= 0) error("sigchld_handler", "Couldn't restart slave %d; it is unresponsive", i); } + #endif //SHELL_OUTPUT_FINISHED siglongjmp(env,1);