Logs from the child process (namespaced) are proxied to the parent

process
This commit is contained in:
Robert Swiecki 2015-05-15 16:02:15 +02:00
parent d203695aa0
commit 69622c17ae
5 changed files with 46 additions and 9 deletions

View File

@ -347,8 +347,11 @@ bool containMakeFdsCOE(void)
return true; return true;
} }
bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_err) bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_err, int fd_log)
{ {
/* Make sure all logs go to the parent process from now on */
logNewLogFD(fd_log);
if (nsjconf->mode != MODE_LISTEN_TCP) { if (nsjconf->mode != MODE_LISTEN_TCP) {
if (nsjconf->is_silent == false) { if (nsjconf->is_silent == false) {
return true; return true;

View File

@ -31,6 +31,6 @@ bool containPrepareEnv(struct nsjconf_t *nsjconf);
bool containMountFS(struct nsjconf_t *nsjconf); bool containMountFS(struct nsjconf_t *nsjconf);
bool containSetLimits(struct nsjconf_t *nsjconf); bool containSetLimits(struct nsjconf_t *nsjconf);
bool containMakeFdsCOE(void); bool containMakeFdsCOE(void);
bool containSetupFD(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err); bool containSetupFD(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err, int fd_log);
#endif /* _CONTAIN_H */ #endif /* _CONTAIN_H */

13
log.c
View File

@ -30,6 +30,7 @@
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/syscall.h>
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
@ -101,7 +102,7 @@ void logLog(enum llevel_t ll, const char *fn, int ln, bool perr, const char *fmt
dprintf(log_fd, "%s", logLevels[ll].prefix); dprintf(log_fd, "%s", logLevels[ll].prefix);
} }
if (logLevels[ll].print_funcline) { if (logLevels[ll].print_funcline) {
dprintf(log_fd, "[%s][%s][%d] %s():%d ", timestr, logLevels[ll].descr, getpid(), fn, ln); dprintf(log_fd, "[%s][%s][%ld] %s():%d ", timestr, logLevels[ll].descr, syscall(__NR_getpid), fn, ln);
} }
va_list args; va_list args;
@ -126,3 +127,13 @@ void logStop(int sig)
{ {
LOG_I("Server stops due to fatal signal (%d) caught. Exiting", sig); LOG_I("Server stops due to fatal signal (%d) caught. Exiting", sig);
} }
void logNewLogFD(int fd)
{
log_fd = fd;
}
void logDirectly(const char *msg)
{
dprintf(log_fd, "%s", msg);
}

2
log.h
View File

@ -55,5 +55,7 @@ bool logInitLogFile(struct nsjconf_t *nsjconf, const char *logfile, bool is_verb
void logLog(enum llevel_t ll, const char *fn, int ln, bool perr, const char *fmt, ...) void logLog(enum llevel_t ll, const char *fn, int ln, bool perr, const char *fmt, ...)
__attribute__ ((format(printf, 5, 6))); __attribute__ ((format(printf, 5, 6)));
void logStop(int sig); void logStop(int sig);
void logNewLogFD(int fd);
void logDirectly(const char *msg);
#endif /* _LOG_H */ #endif /* _LOG_H */

View File

@ -23,6 +23,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <sched.h> #include <sched.h>
#include <signal.h> #include <signal.h>
@ -44,12 +45,12 @@
#include "net.h" #include "net.h"
#include "sandbox.h" #include "sandbox.h"
static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err) static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err, int pipefd)
{ {
if (containPrepareEnv(nsjconf) == false) { if (containPrepareEnv(nsjconf) == false) {
exit(1); exit(1);
} }
if (containSetupFD(nsjconf, fd_in, fd_out, fd_err) == false) { if (containSetupFD(nsjconf, fd_in, fd_out, fd_err, pipefd) == false) {
exit(1); exit(1);
} }
if (containMountFS(nsjconf) == false) { if (containMountFS(nsjconf) == false) {
@ -81,8 +82,10 @@ static int subprocNewProc(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int
LOG_D(" Arg[%d]: '%s'", i, nsjconf->argv[i]); LOG_D(" Arg[%d]: '%s'", i, nsjconf->argv[i]);
} }
execve(nsjconf->argv[0], &nsjconf->argv[0], env); execve(nsjconf->argv[0], &nsjconf->argv[0], env);
PLOG_F("execve('%s')", nsjconf->argv[0]);
exit(1); PLOG_E("execve('%s') failed", nsjconf->argv[0]);
_exit(1);
} }
static void subprocAdd(struct nsjconf_t *nsjconf, pid_t pid, int sock) static void subprocAdd(struct nsjconf_t *nsjconf, pid_t pid, int sock)
@ -135,7 +138,9 @@ void subprocDisplay(struct nsjconf_t *nsjconf)
struct pids_t *p; struct pids_t *p;
LIST_FOREACH(p, &nsjconf->pids, pointers) { LIST_FOREACH(p, &nsjconf->pids, pointers) {
time_t diff = now - p->start; time_t diff = now - p->start;
LOG_I("PID: %d, Remote host: %s, Run time: %ld sec.", p->pid, p->remote_txt, (long)diff); time_t left = nsjconf->tlimit ? nsjconf->tlimit - diff : 0;
LOG_I("PID: %d, Remote host: %s, Run time: %ld sec. (time left: %ld sec.)", p->pid, p->remote_txt,
(long)diff, (long)left);
} }
} }
@ -201,9 +206,15 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er
LOG_D("Creating new process with clone flags: %#x", flags); LOG_D("Creating new process with clone flags: %#x", flags);
int pipefd[2];
if (pipe2(pipefd, O_CLOEXEC) == -1) {
PLOG_E("pipe2(pipefd, O_CLOEXEC) failed");
return;
}
pid_t pid = syscall(__NR_clone, flags, NULL, NULL, NULL, 0); pid_t pid = syscall(__NR_clone, flags, NULL, NULL, NULL, 0);
if (pid == 0) { if (pid == 0) {
subprocNewProc(nsjconf, fd_in, fd_out, fd_err); subprocNewProc(nsjconf, fd_in, fd_out, fd_err, pipefd[1]);
} }
if (pid == -1) { if (pid == -1) {
PLOG_E("clone(flags=%#x) failed. You probably need root privileges if your system " PLOG_E("clone(flags=%#x) failed. You probably need root privileges if your system "
@ -212,6 +223,16 @@ void subprocRunChild(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_er
return; return;
} }
char log_buf[4096];
ssize_t sz;
while ((sz = read(pipefd[0], log_buf, sizeof(log_buf) - 1)) > 0) {
log_buf[sz] = '\0';
logDirectly(log_buf);
}
close(pipefd[0]);
close(pipefd[1]);
subprocAdd(nsjconf, pid, fd_in); subprocAdd(nsjconf, pid, fd_in);
char cs_addr[64]; char cs_addr[64];