--- vzctl-3.0.23.org/src/lib/env.c 2008-12-16 10:04:40.000000000 +0100 +++ vzctl-3.0.23/src/lib/env.c 2008-12-18 08:44:19.000000000 +0100 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -307,7 +308,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)); @@ -394,12 +395,80 @@ */ 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)) { + + dup2(fd, 1); // STDOUT = /dev/null + dup2(fd, 2); // STDERR = /dev/null + + if (res->misc.initlog == 1) { + int master, slave, pid; + mode_t mode; + struct stat st; + + mode = (S_IFCHR | S_IRUSR | S_IWUSR); + + // make sure the device files exist + mknod ("/dev/ptyp0", mode, makedev (2,0)); + mknod ("/dev/ttyp0", mode, makedev (3,0)); + + if ((master = open ("/dev/ptyp0", O_RDWR)) == -1) { + logger(-1, errno, "open ptyp0 failed"); + return 0; + } + + // create new /dev/console ==> /dev/ttyp0 + unlink ("/dev/console"); + mknod ("/dev/console", mode, makedev (3,0)); + + pid = fork(); + + if (pid == -1) { + logger(-1, errno, "unable to fork init-logger"); + return 0; + } + + if (!pid) { + + close(wait_p); close(err_p); + + close(STDIN_FILENO); + dup2(master, STDIN_FILENO); + + close(STDOUT_FILENO); + open("/var/log/init.log", O_CREAT|O_WRONLY|O_TRUNC); + + close(STDERR_FILENO); + dup2(STDOUT_FILENO, STDERR_FILENO); + + execl ("/bin/cat", "init-logger", NULL); + exit (-1); + } + + close (master); + + if ((slave = open ("/dev/ttyp0", O_RDWR)) == -1) { + logger(-1, errno, "open ttyp0 failed"); + return 0; + } + + close(STDIN_FILENO); + dup2(slave, STDIN_FILENO); + + close(STDOUT_FILENO); + dup2(slave, STDOUT_FILENO); + + close(STDERR_FILENO); + dup2(STDOUT_FILENO, STDERR_FILENO); + + // tell init to use /dev/ttyp0 + envp[2] = "CONSOLE=/dev/ttyp0"; + } + } + + execve("/sbin/init", argv, envp); execve("/etc/init", argv, envp); execve("/bin/init", argv, envp); --- vzctl-3.0.23.org/src/lib/config.c 2008-12-16 10:04:40.000000000 +0100 +++ vzctl-3.0.23/src/lib/config.c 2008-12-17 15:07:59.000000000 +0100 @@ -57,6 +57,7 @@ {"LOG_LEVEL", NULL, PARAM_LOGLEVEL}, {"LOGFILE", NULL, PARAM_LOGFILE}, {"VERBOSE", NULL, PARAM_VERBOSE}, +{"INITLOG", NULL, PARAM_INITLOG}, {"IPTABLES", NULL, PARAM_IPTABLES}, /* UB */ @@ -192,6 +193,8 @@ {"cpuweight", required_argument, NULL, PARAM_CPUWEIGHT}, {"cpulimit", required_argument, NULL, PARAM_CPULIMIT}, {"cpus", required_argument, NULL, PARAM_VCPUS}, +/* misc param */ +{"initlog", required_argument, NULL, PARAM_INITLOG}, /* create param */ {"onboot", required_argument, NULL, PARAM_ONBOOT}, {"setmode", required_argument, NULL, PARAM_SETMODE}, @@ -1208,6 +1211,9 @@ ret = 0; switch (conf->id) { + case PARAM_INITLOG: + ret = conf_store_yesno(conf_h, conf->name, misc->initlog); + break; case PARAM_ONBOOT: ret = conf_store_yesno(conf_h, conf->name, vps_p->opt.onboot); break; @@ -1909,6 +1915,9 @@ case PARAM_LOGGING: ret = conf_parse_yesno(&vps_p->log.enable, val, 1); break; + case PARAM_INITLOG: + ret = conf_parse_yesno(&vps_p->res.misc.initlog, val, 1); + break; case PARAM_LOGLEVEL: if (parse_int(val, &int_id)) break; @@ -2734,6 +2743,7 @@ MERGE_STR(hostname) MERGE_STR(description) MERGE_INT(wait); + MERGE_INT(initlog); } static void merge_dq(dq_param *dst, dq_param *src) --- vzctl-3.0.23.org/etc/vz.conf 2008-12-16 10:04:40.000000000 +0100 +++ vzctl-3.0.23/etc/vz.conf 2008-12-17 15:07:59.000000000 +0100 @@ -10,6 +10,9 @@ LOG_LEVEL=0 VERBOSE=0 +## log output of init process to $VE_ROOT/var/log/init.log +INITLOG=yes + ## Disk quota parameters DISK_QUOTA=yes VZFASTBOOT=no --- vzctl-3.0.23.org/include/res.h 2008-12-16 10:04:40.000000000 +0100 +++ vzctl-3.0.23/include/res.h 2008-12-17 15:07:59.000000000 +0100 @@ -53,6 +53,7 @@ char *hostname; char *description; int wait; + int initlog; } misc_param; struct mod_action; --- vzctl-3.0.23.org/include/vzctl_param.h 2008-12-16 10:04:40.000000000 +0100 +++ vzctl-3.0.23/include/vzctl_param.h 2008-12-17 15:07:59.000000000 +0100 @@ -134,6 +134,7 @@ #define PARAM_NETIF_MAC_FILTER 360 #define PARAM_NETIF_BRIDGE 361 #define PARAM_DESCRIPTION 362 +#define PARAM_INITLOG 363 #define PARAM_LINE "e:p:f:t:i:l:k:a:b:n:x:h" #endif --- vzctl-3.0.23.org/man/vps.conf.5 2008-12-16 10:04:40.000000000 +0100 +++ vzctl-3.0.23/man/vps.conf.5 2008-12-17 15:07:59.000000000 +0100 @@ -30,6 +30,13 @@ Default is \fBno\fR, meaning the container will not be started if \fBONBOOT\fR parameter is omitted. Corresponds to the \fB--onboot\fR option. +.IP \fBINITLOG\fR="\fByes\fR|\fBno\fR" +If enabled init output is logged to /var/log/init.log. This is done by +opening a BSD pseudo terminal device. A new /dev/console is created and points +to that pseudo terminal slave. An additional process started +inside the container (init-logger) reads the master and write results +to /var/log/init.log. +Corresponds to the \fB--initlog\fR option. .IP \fBOSTEMPLATE\fR="\fItmpl_name\fR" Corresponds to the \fB--ostemplate\fR option. .IP \fBVE_ROOT\fR="\fIdirectory\fR"