Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,11 @@ | |
|
||
#include <glib.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/msg_xml.h> | ||
|
@@ -391,6 +396,119 @@ void handle_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 = 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 */ | ||
{ | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
kgaillot
Contributor
|
||
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* */ | ||
static struct crm_option long_options[] = { | ||
/* Top-level Options */ | ||
|
@@ -410,12 +528,14 @@ static struct crm_option long_options[] = { | |
/* *INDENT-ON* */ | ||
|
||
int | ||
main(int argc, char **argv) | ||
main(int argc, char **argv, char **envp) | ||
{ | ||
int flag = 0; | ||
int index = 0; | ||
const char *option = NULL; | ||
|
||
/* If necessary, create PID1 now before any FDs are opened */ | ||
spawn_pidone(argc, argv, envp); | ||
|
||
#ifndef ENABLE_PCMK_REMOTE | ||
crm_log_preinit("lrmd", argc, argv); | ||
|
So the purpose of the conditional compilation is to only proceed if there's (nonportable) implicit backup of the original name?
libqb
does not use this backup AFAIK, not sure about the libc functions.Does it make sense to spoof itself to out-of-cointainer world? I don't think in-container processes would care, and in many containers running scenario there will be just a bunch of pcmk-init processes (as opposed to pacemaker_remoted?). It might make sense to have a suffix denoting the container nesting level, supposing it will get somehow propagated as environment variables?