--- startpar.c +++ startpar.c 2009-03-27 11:48:00.080002479 +0100 @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include #include @@ -64,6 +66,8 @@ static struct timeval lastlim; static char *run_mode = NULL; static struct makenode **nodevec; +static enum { Unknown, Preload, NoPreload } ispreload = Unknown; + #define PBUF_SIZE 8192 struct prg { char *name; @@ -81,6 +85,19 @@ static int inpar, par; static int pidpipe[2]; static double iorate = 800.0; +void sighandler_nopreload(int x) +{ + (void)x; + ispreload = NoPreload; +} + + +void sighandler_preload(int x) +{ + (void)x; + ispreload = Preload; +} + void *xcalloc(size_t nmemb, size_t size) { void *r; @@ -248,11 +265,15 @@ static int checksystem(const int par, co if (read_proc(&prcs_run, &prcs_blked)) return par; + /* if we have preload running, we expect I/O not to be a problem */ + if (ispreload != NoPreload) + prcs_blked = 0; + newpar = (par*numcpu) - prcs_run + 1; /* +1 for startpar its self */ newpar -= (int)(((double)prcs_blked)*iorate); /* I/O load reduction */ #if DEBUG - fprintf(stderr, "checksystem par=%d newpar=%d (prcs_run=%u) %ld\n", par, newpar, prcs_run, time(0)); + fprintf(stderr, "checksystem par=%d newpar=%d (prcs_run=%lu) %ld\n", par, newpar, prcs_run, time(0)); dump_status(); #endif if (newpar <= 0) @@ -271,9 +292,12 @@ static inline int checkpar(const int par return checksystem(par, start, false); } +#define SOCK_PATH "/dev/shm/preload_sock" + void run(struct prg *p) { char *m = 0; + pid_t parent = getpid(); p->len = 0; p->pid = (pid_t)0; @@ -341,6 +365,41 @@ void run(struct prg *p) closeall(); + if (!strcmp(arg, "start")) + { + int s, t, len; + struct sockaddr_un remote; + char str[100]; + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s != -1) + { + memset(&remote, 0, sizeof(struct sockaddr_un)); + remote.sun_family = AF_UNIX; + strcpy(remote.sun_path, SOCK_PATH); + len = strlen(remote.sun_path) + sizeof(remote.sun_family); + + t = connect(s, (struct sockaddr *)&remote, len); + if (t != -1) + { + if (ispreload != Preload) + kill(parent, SIGUSR1); + send(s, p->name, strlen(p->name), 0); + recv(s, str, 100, 0); + } + else if ( ispreload == Unknown) + { + /* + * if we connected to preload once, we know it ran. + * In case we can't connect to it later, it means it did + * its job and we can guess I/O is no longer a problem. + */ + kill(parent, SIGUSR2); + } + close(s); + } + } + if (run_mode) { char path[128]; @@ -557,6 +616,9 @@ int main(int argc, char **argv) char *run_level = getenv("RUNLEVEL"); char *splashopt = 0; + (void)signal(SIGUSR1, sighandler_preload); + (void)signal(SIGUSR2, sighandler_nopreload); + (void)signal(SIGCHLD, SIG_DFL); numcpu = sysconf(_SC_NPROCESSORS_ONLN); myname = argv[0];