Skip to content

Commit 8abdd82

Browse files
committed
lrmd: Have pacemaker-remote reap zombies if it is running as pid 1
1 parent 26c59fb commit 8abdd82

File tree

2 files changed

+131
-1
lines changed

2 files changed

+131
-1
lines changed

configure.ac

+10
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,16 @@ if test "$ac_cv_header_libxslt_xslt_h" != "yes"; then
823823
AC_MSG_ERROR(The libxslt developement headers were not found)
824824
fi
825825

826+
AC_CACHE_CHECK(whether __progname and __progname_full are available,
827+
pf_cv_var_progname,
828+
AC_TRY_LINK([extern char *__progname, *__progname_full;],
829+
[__progname = "foo"; __progname_full = "foo bar";],
830+
pf_cv_var_progname="yes", pf_cv_var_progname="no"))
831+
832+
if test "$pf_cv_var_progname" = "yes"; then
833+
AC_DEFINE(HAVE___PROGNAME,1,[ ])
834+
fi
835+
826836
dnl ========================================================================
827837
dnl Structures
828838
dnl ========================================================================

lrmd/main.c

+121-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@
2121

2222
#include <glib.h>
2323
#include <unistd.h>
24+
#include <signal.h>
25+
26+
#include <sys/types.h>
27+
#include <sys/wait.h>
28+
#include <sys/prctl.h>
2429

2530
#include <crm/crm.h>
2631
#include <crm/msg_xml.h>
@@ -391,6 +396,119 @@ void handle_shutdown_nack()
391396
crm_debug("Ignoring unexpected shutdown nack");
392397
}
393398

399+
400+
static pid_t main_pid = 0;
401+
static void
402+
sigdone(void)
403+
{
404+
exit(0);
405+
}
406+
407+
static void
408+
sigreap(void)
409+
{
410+
pid_t pid = 0;
411+
int status;
412+
do {
413+
/*
414+
* Opinions seem to differ as to what to put here:
415+
* -1, any child process
416+
* 0, any child process whose process group ID is equal to that of the calling process
417+
*/
418+
pid = waitpid(-1, &status, WNOHANG);
419+
if(pid == main_pid) {
420+
/* Exit when pacemaker-remote exits and use the same return code */
421+
if (WIFEXITED(status)) {
422+
exit(WEXITSTATUS(status));
423+
}
424+
exit(1);
425+
}
426+
427+
} while (pid > 0);
428+
}
429+
430+
static struct {
431+
int sig;
432+
void (*handler)(void);
433+
} sigmap[] = {
434+
{ SIGCHLD, sigreap },
435+
{ SIGINT, sigdone },
436+
};
437+
438+
static void spawn_pidone(int argc, char **argv, char **envp)
439+
{
440+
sigset_t set;
441+
442+
if (getpid() != 1) {
443+
return;
444+
}
445+
446+
sigfillset(&set);
447+
sigprocmask(SIG_BLOCK, &set, 0);
448+
449+
main_pid = fork();
450+
switch (main_pid) {
451+
case 0:
452+
sigprocmask(SIG_UNBLOCK, &set, NULL);
453+
setsid();
454+
setpgid(0, 0);
455+
456+
/* Child remains as pacemaker_remoted */
457+
return;
458+
case -1:
459+
perror("fork");
460+
}
461+
462+
/* Parent becomes the reaper of zombie processes */
463+
/* Safe to initialize logging now if needed */
464+
465+
#ifdef HAVE___PROGNAME
466+
/* Differentiate ourselves in the 'ps' output */
467+
{
468+
char *p;
469+
int i, maxlen;
470+
char *LastArgv = NULL;
471+
const char *name = "pcmk-init";
472+
473+
for(i = 0; i < argc; i++) {
474+
if(!i || (LastArgv + 1 == argv[i]))
475+
LastArgv = argv[i] + strlen(argv[i]);
476+
}
477+
478+
for(i = 0; envp[i] != NULL; i++) {
479+
if((LastArgv + 1) == envp[i]) {
480+
LastArgv = envp[i] + strlen(envp[i]);
481+
}
482+
}
483+
484+
maxlen = (LastArgv - argv[0]) - 2;
485+
486+
i = strlen(name);
487+
/* We can overwrite individual argv[] arguments */
488+
snprintf(argv[0], maxlen, "%s", name);
489+
490+
/* Now zero out everything else */
491+
p = &argv[0][i];
492+
while(p < LastArgv)
493+
*p++ = '\0';
494+
argv[1] = NULL;
495+
}
496+
#endif /* HAVE___PROGNAME */
497+
498+
while (1) {
499+
int sig;
500+
size_t i;
501+
502+
sigwait(&set, &sig);
503+
for (i = 0; i < DIMOF(sigmap); i++) {
504+
if (sigmap[i].sig == sig) {
505+
sigmap[i].handler();
506+
break;
507+
}
508+
}
509+
}
510+
}
511+
394512
/* *INDENT-OFF* */
395513
static struct crm_option long_options[] = {
396514
/* Top-level Options */
@@ -410,12 +528,14 @@ static struct crm_option long_options[] = {
410528
/* *INDENT-ON* */
411529

412530
int
413-
main(int argc, char **argv)
531+
main(int argc, char **argv, char **envp)
414532
{
415533
int flag = 0;
416534
int index = 0;
417535
const char *option = NULL;
418536

537+
/* If necessary, create PID1 now before any FDs are opened */
538+
spawn_pidone(argc, argv, envp);
419539

420540
#ifndef ENABLE_PCMK_REMOTE
421541
crm_log_preinit("lrmd", argc, argv);

0 commit comments

Comments
 (0)