--- vzctl-3.0.20.org/src/lib/env.c	2007-12-14 11:13:24.000000000 +0100
+++ vzctl-3.0.20/src/lib/env.c	2007-12-14 11:33:58.000000000 +0100
@@ -23,6 +23,7 @@
 #include <signal.h>
 #include <fcntl.h>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <sys/wait.h>
 #include <string.h>
 #include <sys/ioctl.h>
@@ -290,6 +291,80 @@
 	return 0;
 }
 
+static int terminate_init_observer = 0;
+
+void 
+_sigterm_handler (int signum)
+{
+  terminate_init_observer = 1;
+}
+
+#define INIT_FIFO "/var/log/init.fifo"
+#define INIT_LOG "/var/log/init.log"
+
+void 
+_observe_init_fifo (void) {
+  struct sigaction act;
+  int fd;
+  int fifo;
+  int len;
+      
+  char buf[4096];
+  char *txt;
+  char txtbuf[4096];
+
+  sigemptyset(&act.sa_mask);
+  act.sa_handler = _sigterm_handler;
+  act.sa_flags = SA_RESETHAND;
+  sigaction(SIGTERM, &act, NULL);
+
+  if ((fd = open(INIT_LOG, O_CREAT|O_WRONLY|O_TRUNC, 0644)) == -1) {
+    exit (-1);
+  }
+
+  if ((fifo = open(INIT_FIFO, O_RDONLY)) == -1) {
+    sprintf (txtbuf, "Error: unable to open fifo: %s\n", strerror(errno));
+    write (fd, txtbuf, strlen (txtbuf));
+    exit (-1);
+  }
+
+  while (1) { 
+
+    len = read (fifo, buf, 4096);
+	
+    if (terminate_init_observer) { // got signal 
+      if (len > 0) {
+	write (fd, buf, len);
+      }
+      break;
+    }
+    if (len == -1) {
+      if (errno == EAGAIN || errno == EINTR) {
+	continue;
+      }
+
+      sprintf (txtbuf, "ERROR: unable to read fifo: %s\n", strerror(errno));
+      write (fd, txtbuf, strlen (txtbuf));
+      break;
+    }
+
+    if (len == 0) { // EOF - try later
+      sleep (1);
+      continue;
+    }
+    write (fd, buf, len);
+  }
+     
+  // terminated - just write a CR
+  txt = "\n"; write (fd, txt, strlen (txt));
+
+  close (fifo);
+  close (fd);
+
+  exit (0);
+}
+
+
 static int _env_create(vps_handler *h, envid_t veid, int wait_p, int err_p,
 	void *data)
 {
@@ -298,7 +373,7 @@
 	int fd, ret;
 	vps_res *res;
 	char *argv[] = {"init", "-z", "      ", NULL};
-	char *envp[] = {"HOME=/", "TERM=linux", NULL};
+	char *envp[] = {"HOME=/", "TERM=linux", NULL, NULL};
 
 	res = (vps_res *) data;
 	memset(&create_param, 0, sizeof(create_param));
@@ -385,12 +460,28 @@
 	*/
 	if (read(wait_p, &ret, sizeof(ret)) != 0)
 		return 0;
-	if ((fd = open("/dev/null", O_RDWR)) != -1) {
-		dup2(fd, 0);
-		dup2(fd, 1);
-		dup2(fd, 2);
-	}
+
 	logger(10, 0, "Starting init");
+
+	if (((fd = open("/dev/null", O_RDWR)) != -1) && (fd == STDIN_FILENO)) {
+
+	  if ((mkfifo (INIT_FIFO, 0600) == 0) || (errno == EEXIST)) {
+	    envp[2] = "CONSOLE=" INIT_FIFO;
+	    if (!fork()) { // observer child
+	      close (wait_p); close (err_p);
+	      _observe_init_fifo ();
+	      exit (-1);
+	    }
+	    // also redirect STDOUT/STDERR to fifo
+	    close(STDOUT_FILENO); open(INIT_FIFO, O_WRONLY);
+	    close(STDERR_FILENO); dup2(STDOUT_FILENO, STDERR_FILENO);
+	  } else {
+	    logger(-1, errno, "unable to create init fifo");
+	    dup2(fd, 1); // STDOUT = /dev/null
+	    dup2(fd, 2); // STDERR = /dev/null
+	  }
+	}
+
 	execve("/sbin/init", argv, envp);
 	execve("/etc/init", argv, envp);
 	execve("/bin/init", argv, envp);
