-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new external helper which is to be used as the process image of the reaper process. By replacing the memory image of mxqd in the long-running reaper, we decrease our memory footprint and avoid problems with undefined behaviour of the libraries (mysql, openssl) we use. Only put functions from mxqd into this program, which need to go here: - Set our thread name (again, because execl() will rest it) so that mxqd can identify us as a reaper process - Fork a user process - Change uid of the user process. mxqd needs to start us with a privileged uid, so that we can open the spool file. - Let the child process execute the user command and arguments - Wait for the child process - get its runtime, resource usage and exit status - Delay, if child finished to fast - Write spool file for mxqd to pick up Everything else (groupid, subreaper, environment, stdout, ...) can be done by mxqd before exec()ing this helper.
- Loading branch information
Showing
3 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
#define _GNU_SOURCE | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <sys/prctl.h> | ||
#include <unistd.h> | ||
#include <sys/resource.h> | ||
#include <sys/time.h> | ||
#include <sys/wait.h> | ||
#include <errno.h> | ||
#include <string.h> | ||
|
||
static const char REAPER_PNAME[] = "mxqd reaper"; | ||
|
||
__attribute__((noreturn)) static void die(char *msg) { | ||
perror(msg); | ||
_exit(1); | ||
} | ||
|
||
int main(int argc, char **argv) { | ||
|
||
if (argc < 5 || strcmp(argv[3], "--") != 0) { | ||
fprintf(stderr, "usage: %s UID SPOOLFILENAME -- CMD [ARGS...]\n", argv[0]); | ||
exit(1); | ||
} | ||
|
||
uid_t uid = atoi(argv[1]); | ||
char *spoolfilename = argv[2]; | ||
char **user_argv = &argv[4]; | ||
|
||
pid_t user_pid; | ||
int user_status = -1; | ||
struct rusage user_rusage; | ||
struct timeval user_time; | ||
|
||
struct timeval starttime; | ||
struct timeval endtime; | ||
|
||
if (prctl(PR_SET_NAME, REAPER_PNAME, NULL, NULL, NULL) == -1) | ||
die("PR_SET_NAME"); | ||
user_pid = fork(); | ||
if (user_pid == 0) { | ||
if (setreuid(uid, uid) == -1) | ||
die("setreuid"); | ||
execvp(user_argv[0], user_argv); | ||
die(user_argv[0]); | ||
} | ||
if (user_pid == -1) | ||
die("fork"); | ||
if (gettimeofday(&starttime, NULL) == -1) | ||
die("gettimeofday"); | ||
while (1) { | ||
int status; | ||
pid_t pid = wait(&status); | ||
if (pid < 0 && errno == ECHILD) | ||
break; | ||
if (pid == user_pid) | ||
user_status = status; | ||
} | ||
if (gettimeofday(&endtime, NULL) == -1) | ||
die("gettimeofday"); | ||
timersub(&endtime, &starttime, &user_time); | ||
if (getrusage(RUSAGE_CHILDREN, &user_rusage) == -1) | ||
die("getrusage"); | ||
|
||
if (user_time.tv_sec<30) { | ||
int wait=30-user_time.tv_sec; | ||
sleep(wait); | ||
} | ||
|
||
char *tmpfilename; | ||
if (asprintf(&tmpfilename, "%s.tmp", spoolfilename) == -1) | ||
die(""); | ||
|
||
FILE *out = fopen(tmpfilename,"w"); | ||
if (out == NULL) | ||
die(tmpfilename); | ||
fprintf(out,"1 %d %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", | ||
getpid(), | ||
user_status, | ||
user_time.tv_sec, user_time.tv_usec, | ||
user_rusage.ru_utime.tv_sec, user_rusage.ru_utime.tv_usec, | ||
user_rusage.ru_stime.tv_sec, user_rusage.ru_stime.tv_usec, | ||
user_rusage.ru_maxrss, | ||
user_rusage.ru_ixrss, | ||
user_rusage.ru_idrss, | ||
user_rusage.ru_isrss, | ||
user_rusage.ru_minflt, | ||
user_rusage.ru_majflt, | ||
user_rusage.ru_nswap, | ||
user_rusage.ru_inblock, | ||
user_rusage.ru_oublock, | ||
user_rusage.ru_msgsnd, | ||
user_rusage.ru_msgrcv, | ||
user_rusage.ru_nsignals, | ||
user_rusage.ru_nvcsw, | ||
user_rusage.ru_nivcsw | ||
); | ||
fflush(out); | ||
fsync(fileno(out)); | ||
fclose(out); | ||
if (rename(tmpfilename, spoolfilename) == -1) | ||
die(spoolfilename); | ||
return 0; | ||
} |