[libvirt] [PATCH] LXC: don't doubly link /dev/console

When a console is configured, /dev/console and /dev/tty1 are created as symlinks to the same underlying pts. This causes problems since a separate getty will be spawned for /dev/console and /dev/tty1, but they are each controlling the same device. This patch makes it so that /dev/console is the sole symlink to the first console, /dev/tty1 to the second, /dev/tty2 to the third and so on. Signed-off-by: Dwight Engen <dwight.engen@oracle.com> --- src/lxc/lxc_container.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index fd8ab16..dcc6b17 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -1034,23 +1034,25 @@ static int lxcContainerSetupDevices(char **ttyPaths, size_t nttyPaths) } for (i = 0; i < nttyPaths; i++) { - char *tty; - if (virAsprintf(&tty, "/dev/tty%zu", i+1) < 0) - return -1; - if (symlink(ttyPaths[i], tty) < 0) { - virReportSystemError(errno, - _("Failed to symlink %s to %s"), - ttyPaths[i], tty); + if (i == 0) { + if (symlink(ttyPaths[i], "/dev/console") < 0) { + virReportSystemError(errno, + _("Failed to symlink %s to /dev/console"), + ttyPaths[i]); + return -1; + } + } else { + char *tty; + if (virAsprintf(&tty, "/dev/tty%zu", i) < 0) + return -1; + if (symlink(ttyPaths[i], tty) < 0) { + virReportSystemError(errno, + _("Failed to symlink %s to %s"), + ttyPaths[i], tty); + VIR_FREE(tty); + return -1; + } VIR_FREE(tty); - return -1; - } - VIR_FREE(tty); - if (i == 0 && - symlink(ttyPaths[i], "/dev/console") < 0) { - virReportSystemError(errno, - _("Failed to symlink %s to /dev/console"), - ttyPaths[i]); - return -1; } } return 0; -- 1.9.0

On Mon, May 5, 2014 at 5:14 PM, Dwight Engen <dwight.engen@oracle.com> wrote:
When a console is configured, /dev/console and /dev/tty1 are created as symlinks to the same underlying pts. This causes problems since a separate getty will be spawned for /dev/console and /dev/tty1, but they are each controlling the same device.
Which init spawns a getty on /dev/console _and_ /dev/tty1? This is odd.
This patch makes it so that /dev/console is the sole symlink to the first console, /dev/tty1 to the second, /dev/tty2 to the third and so on.
Signed-off-by: Dwight Engen <dwight.engen@oracle.com> --- src/lxc/lxc_container.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c index fd8ab16..dcc6b17 100644 --- a/src/lxc/lxc_container.c +++ b/src/lxc/lxc_container.c @@ -1034,23 +1034,25 @@ static int lxcContainerSetupDevices(char **ttyPaths, size_t nttyPaths) }
for (i = 0; i < nttyPaths; i++) { - char *tty; - if (virAsprintf(&tty, "/dev/tty%zu", i+1) < 0) - return -1; - if (symlink(ttyPaths[i], tty) < 0) { - virReportSystemError(errno, - _("Failed to symlink %s to %s"), - ttyPaths[i], tty); + if (i == 0) { + if (symlink(ttyPaths[i], "/dev/console") < 0) { + virReportSystemError(errno, + _("Failed to symlink %s to /dev/console"), + ttyPaths[i]); + return -1; + } + } else { + char *tty; + if (virAsprintf(&tty, "/dev/tty%zu", i) < 0) + return -1; + if (symlink(ttyPaths[i], tty) < 0) { + virReportSystemError(errno, + _("Failed to symlink %s to %s"), + ttyPaths[i], tty); + VIR_FREE(tty); + return -1; + } VIR_FREE(tty); - return -1; - } - VIR_FREE(tty); - if (i == 0 && - symlink(ttyPaths[i], "/dev/console") < 0) { - virReportSystemError(errno, - _("Failed to symlink %s to /dev/console"), - ttyPaths[i]); - return -1; } } return 0; -- 1.9.0
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list
-- Thanks, //richard

On Mon, May 05, 2014 at 11:14:18AM -0400, Dwight Engen wrote:
When a console is configured, /dev/console and /dev/tty1 are created as symlinks to the same underlying pts. This causes problems since a separate getty will be spawned for /dev/console and /dev/tty1, but they are each controlling the same device.
That is simply a bug in the OS setup IMHO. FYI systemd specified that the 'container_ttys' env variable should be set to indicate which devices a gettty should be spawned on and libvirt now sets that. We intentionally exclude tty1 from the container_ttys env var so we don't get the double-getty with any systemd enabled OS. IMHO even non-systemd OS could read that env var to decide where to spawn getttys See also this doc: http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/
This patch makes it so that /dev/console is the sole symlink to the first console, /dev/tty1 to the second, /dev/tty2 to the third and so on.
This is a backwards-incompatible change that is likely to break existing deployments I'm afraid, so we can't do that IMHO. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|

On Tue, 6 May 2014 11:27:47 +0100 "Daniel P. Berrange" <berrange@redhat.com> wrote:
On Mon, May 05, 2014 at 11:14:18AM -0400, Dwight Engen wrote:
When a console is configured, /dev/console and /dev/tty1 are created as symlinks to the same underlying pts. This causes problems since a separate getty will be spawned for /dev/console and /dev/tty1, but they are each controlling the same device.
That is simply a bug in the OS setup IMHO.
I agree it doesn't make sense when /dev/console is 5:1 and is tracking the current vt via tty0, but in a container situation where its just another pty spawning a getty on it makes sense. I ran into this because I was testing the compatibility of the containers setup by lxc templates with libvirt-lxc, and most of them set up a getty on /dev/console since it's a separate pty. I was hoping to avoid this environmental difference in the way the container is setup between lxc and libvirt-lxc so that container's contents wouldn't have to know about it.
FYI systemd specified that the 'container_ttys' env variable should be set to indicate which devices a gettty should be spawned on and libvirt now sets that. We intentionally exclude tty1 from the container_ttys env var so we don't get the double-getty with any systemd enabled OS.
IMHO even non-systemd OS could read that env var to decide where to spawn getttys
I noticed that the ubuntu upstart job checks for container=lxc before spawning a getty on the console, so it seems like that may be the best approach since it should also work in a non-container case as well. Thanks for the feedback.
See also this doc:
http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface/
This patch makes it so that /dev/console is the sole symlink to the first console, /dev/tty1 to the second, /dev/tty2 to the third and so on.
This is a backwards-incompatible change that is likely to break existing deployments I'm afraid, so we can't do that IMHO.
Regards, Daniel
participants (3)
-
Daniel P. Berrange
-
Dwight Engen
-
Richard Weinberger