Skip to content

Commit

Permalink
lrmd: Have pacemaker-remote reap zombies if it is running as pid 1
Browse files Browse the repository at this point in the history
  • Loading branch information
beekhof committed Apr 20, 2017
1 parent 26c59fb commit e7e9e6c
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 1 deletion.
10 changes: 10 additions & 0 deletions configure.ac
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -823,6 +823,16 @@ if test "$ac_cv_header_libxslt_xslt_h" != "yes"; then
AC_MSG_ERROR(The libxslt developement headers were not found) AC_MSG_ERROR(The libxslt developement headers were not found)
fi fi


AC_CACHE_CHECK(whether __progname and __progname_full are available,
pf_cv_var_progname,
AC_TRY_LINK([extern char *__progname, *__progname_full;],
[__progname = "foo"; __progname_full = "foo bar";],
pf_cv_var_progname="yes", pf_cv_var_progname="no"))

if test "$pf_cv_var_progname" = "yes"; then
AC_DEFINE(HAVE___PROGNAME,1,[ ])
fi

dnl ======================================================================== dnl ========================================================================
dnl Structures dnl Structures
dnl ======================================================================== dnl ========================================================================
Expand Down
122 changes: 121 additions & 1 deletion lrmd/main.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@


#include <glib.h> #include <glib.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h>

#include <sys/types.h>
#include <sys/wait.h>
#include <sys/prctl.h>


#include <crm/crm.h> #include <crm/crm.h>
#include <crm/msg_xml.h> #include <crm/msg_xml.h>
Expand Down Expand Up @@ -391,6 +396,119 @@ void handle_shutdown_nack()
crm_debug("Ignoring unexpected shutdown nack"); crm_debug("Ignoring unexpected shutdown nack");
} }



static pid_t main_pid = 0;
static void
sigdone(void)
{
exit(0);
}

static void
sigreap(void)
{
pid_t pid = 0;
int status;
do {
/*
* Opinions seem to differ as to what to put here:
* -1, any child process
* 0, any child process whose process group ID is equal to that of the calling process
*/
pid = waitpid(-1, &status, WNOHANG);
if(pid == main_pid) {
/* Exit when pacemaker-remote exits and use the same return code */
if (WIFEXITED(status)) {
exit(WEXITSTATUS(status));
}
exit(1);
}

} while (pid > 0);
}

static struct {
int sig;
void (*handler)(void);
} sigmap[] = {
{ SIGCHLD, sigreap },
{ SIGINT, sigdone },
};

static void spawn_pidone(int argc, char **argv, char **envp)
{
sigset_t set;

if (getpid() != 1) {
return;
}

sigfillset(&set);
sigprocmask(SIG_BLOCK, &set, 0);

main_pid = 1;//fork();
switch (main_pid) {
case 0:
sigprocmask(SIG_UNBLOCK, &set, NULL);
setsid();
setpgid(0, 0);

/* Child remains as pacemaker_remoted */
return;
case -1:
perror("fork");
}

/* Parent becomes the reaper of zombie processes */
/* Safe to initialize logging now if needed */

#ifdef HAVE___PROGNAME
/* Differentiate ourselves in the 'ps' output */
{
char *p;
int i, maxlen;
char *LastArgv = NULL;
const char *name = "pcmk-init";

for(i = 0; i < argc; i++) {
if(!i || (LastArgv + 1 == argv[i]))
LastArgv = argv[i] + strlen(argv[i]);
}

for(i = 0; envp[i] != NULL; i++) {
if((LastArgv + 1) == envp[i]) {
LastArgv = envp[i] + strlen(envp[i]);
}
}

maxlen = (LastArgv - argv[0]) - 2;

i = strlen(name);
/* We can overwrite individual argv[] arguments */
snprintf(argv[0], maxlen, "%s", name);

/* Now zero out everything else */
p = &argv[0][i];
while(p < LastArgv)
*p++ = '\0';
argv[1] = NULL;
}
#endif /* HAVE___PROGNAME */

while (1) {
int sig;
size_t i;

sigwait(&set, &sig);
for (i = 0; i < DIMOF(sigmap); i++) {
if (sigmap[i].sig == sig) {
sigmap[i].handler();
break;
}
}
}
}

/* *INDENT-OFF* */ /* *INDENT-OFF* */
static struct crm_option long_options[] = { static struct crm_option long_options[] = {
/* Top-level Options */ /* Top-level Options */
Expand All @@ -410,12 +528,14 @@ static struct crm_option long_options[] = {
/* *INDENT-ON* */ /* *INDENT-ON* */


int int
main(int argc, char **argv) main(int argc, char **argv, char **envp)
{ {
int flag = 0; int flag = 0;
int index = 0; int index = 0;
const char *option = NULL; const char *option = NULL;


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


#ifndef ENABLE_PCMK_REMOTE #ifndef ENABLE_PCMK_REMOTE
crm_log_preinit("lrmd", argc, argv); crm_log_preinit("lrmd", argc, argv);
Expand Down

0 comments on commit e7e9e6c

Please sign in to comment.