Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add mxq_reaper
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
donald committed May 5, 2022
1 parent f12d171 commit f752a60
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -30,6 +30,7 @@ parser.tab.o
test_parser.o
test_parser
ppidcache.o
mxq_reaper.o

mxqsub
/mxqsub.1
Expand All @@ -44,6 +45,7 @@ test_mx_log
test_mx_mysq
test_mxqd_control
test_keywordset
mxq_reaper

/web/pages/mxq/mxq
web/lighttpd.conf
Expand Down
7 changes: 7 additions & 0 deletions Makefile
Expand Up @@ -656,6 +656,13 @@ build: mxqps

clean: CLEAN += mxqps

### mxqps -------------------------------------------------------------

clean: CLEAN += mxq_reaper.o mxq_reaper
build: mxq_reaper
install:: mxq_reaper
$(call quiet-install,0755,$^,${DESTDIR}${LIBEXECDIR}/mxq/mxq_reaper)

### script helper -----------------------------------------------------

install:: helper/tmpdir-setup
Expand Down
104 changes: 104 additions & 0 deletions mxq_reaper.c
@@ -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;
}

0 comments on commit f752a60

Please sign in to comment.