Logs from the child process (namespaced) are proxied to the parent
authorRobert Swiecki <swiecki@google.com>
Fri, 15 May 2015 14:02:15 +0000 (16:02 +0200)
committerRobert Swiecki <swiecki@google.com>
Fri, 15 May 2015 14:02:15 +0000 (16:02 +0200)
process

contain.c
contain.h
log.c
log.h
subproc.c

index 7774756deb71d7ad7fcf3804c12e9b8cb456bd9d..a6cf60b8e98c681adf4a213ab301669f31206017 100644 (file)
--- a/contain.c
+++ b/contain.c
@@ -347,8 +347,11 @@ bool containMakeFdsCOE(void)
        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->is_silent == false) {
                        return true;
index c61436d522be996305904327df4615e2204897e3..9d97729e7e30920bd82cdc9553f12473e261a96f 100644 (file)
--- a/contain.h
+++ b/contain.h
@@ -31,6 +31,6 @@ bool containPrepareEnv(struct nsjconf_t *nsjconf);
 bool containMountFS(struct nsjconf_t *nsjconf);
 bool containSetLimits(struct nsjconf_t *nsjconf);
 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 */
diff --git a/log.c b/log.c
index 8f73ef091e782af796a9662bee6eea896f708529..01f18df2420a2b3edda567d11b60c85c3444a73c 100644 (file)
--- a/log.c
+++ b/log.c
@@ -30,6 +30,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/syscall.h>
 #include <time.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);
        }
        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;
@@ -126,3 +127,13 @@ void logStop(int 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);
+}
diff --git a/log.h b/log.h
index 0de3c4d4892ce94f863469d293018c9407f177ef..e16ff51d153a175a27d264f814d44de392a32d4b 100644 (file)
--- a/log.h
+++ b/log.h
@@ -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, ...)
     __attribute__ ((format(printf, 5, 6)));
 void logStop(int sig);
+void logNewLogFD(int fd);
+void logDirectly(const char *msg);
 
 #endif                         /* _LOG_H */
index 87c398e4bcba871016d641681fd4f03e1f36e962..808473266a27785b2256c204a93c2de1929fda6f 100644 (file)
--- a/subproc.c
+++ b/subproc.c
@@ -23,6 +23,7 @@
 
 #include <arpa/inet.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <netinet/in.h>
 #include <sched.h>
 #include <signal.h>
 #include "net.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) {
                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);
        }
        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]);
        }
        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)
@@ -135,7 +138,9 @@ void subprocDisplay(struct nsjconf_t *nsjconf)
        struct pids_t *p;
        LIST_FOREACH(p, &nsjconf->pids, pointers) {
                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);
 
+       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);
        if (pid == 0) {
-               subprocNewProc(nsjconf, fd_in, fd_out, fd_err);
+               subprocNewProc(nsjconf, fd_in, fd_out, fd_err, pipefd[1]);
        }
        if (pid == -1) {
                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;
        }
 
+       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);
 
        char cs_addr[64];