X-Git-Url: http://git.tuebingen.mpg.de/?a=blobdiff_plain;f=server.c;h=da55b99923621975335a86a7dfbbad41e3e6a573;hb=e0acbd356abf4d9f1b693065b1ff23c57c53ab1e;hp=a4115eb65734391128481f6fa421d548aba78e20;hpb=ad81d625737e1c096c154aedd8a1d161d3ee592e;p=paraslash.git diff --git a/server.c b/server.c index a4115eb6..da55b999 100644 --- a/server.c +++ b/server.c @@ -291,15 +291,32 @@ static void signal_post_select(struct sched *s, struct task *t) if (pid != mmd->afs_pid) continue; PARA_EMERG_LOG("fatal: afs died\n"); - goto genocide; + kill(0, SIGTERM); + goto cleanup; } break; /* die on sigint/sigterm. Kill all children too. */ case SIGINT: case SIGTERM: PARA_EMERG_LOG("terminating on signal %d\n", st->signum); -genocide: kill(0, SIGTERM); + /* + * We must wait for afs because afs catches SIGINT/SIGTERM. + * Before reacting to the signal, afs might want to use the + * shared memory area and the mmd mutex. If we destroy this + * mutex too early and afs tries to lock the shared memory + * area, the call to mutex_lock() will fail and terminate the + * afs process. This leads to dirty osl tables. + * + * There's no such problem with the other children of the + * server process (the command handlers) as these reset their + * SIGINT/SIGTERM handlers to the default action, i.e. these + * processes get killed immediately by the above kill(). + */ + PARA_INFO_LOG("waiting for afs (pid %d) to die\n", + (int)mmd->afs_pid); + waitpid(mmd->afs_pid, NULL, 0); +cleanup: free(mmd->afd.afhi.chunk_table); free(mmd->afd.afhi.info_string); close_listed_fds();