From: Dan S. <da...@sh...> - 2004-01-23 03:54:34
|
A basic draft. Dan Shearer Jan '04 (This might be on the way to a more comprehensive document about console channels in general) How the 'port' console channel works ------------------------------------ This facility allows a UML's virtual console or serial line console (/dev/ttyx or /dev/sslx from within UML) to be connected to a listening port on the host system. You can telnet to that port and login, without the UML having any networking configured. 0. About console channel driver Each channel corresponds to an imaginary hardware device which can be hooked directly up to the tty devices running inside UML. The files drivers/chan_kern.c and chan_user.c define abstractions for consoles. When UML writes to a tty it does so through these functions. 1. About telnetd telnetd connects a network socket with a pty and interprets terminal protocol commands if they appear with the data that it is relaying between the socket and the pty. The socket gets passed to telnetd by some program (such inetd, or UML in this case) in file descriptor 0 passed during the exec call. telnetd allocates the next free pts (eg /dev/pts/1, if Unix98 ptys are in use) and receives a file descriptor for it. telnetd then execs the login program with stdin/out/err all containing the file descriptor number of the pts device. The login program keeps running for the length of the session (it isn't just for authentication.) The login program normally execs a shell, and the shell just interacts on stdio as usual. Some telnetd's have a a -L parameter that specify a login program. This login program may do some authentication. In the case of UML it does no authentication, just relays characters between file descriptors. 2. About the port console channel telnetd is used to process the telnet protocol, but not to connect with a shell (because there is no shell involved here, except within UML and that is not relevant to the console channel.) What is required is that data coming from a telnet client go through telnetd, which strips off all but the data, and then that data gets sent back into UML to be delivered to the tty device, which is usually connected to a getty process in /etc/inittab. The mechanism for getting data back into UML is as follows: Before execing telnetd, UML first allocates a new pipe. The socket number for that pipe is passed in file descriptor 3. File descriptors are inherited with exec, so the login program gets it as well The login program, which is receiving data from the master side of the pty that telnetd opened, sends the data back through this pipe The relevant files are arch/um/drivers/port_user.c and port_kern.c. 3. Problems with this scheme a. inflexible. You can't have the raw data from the console port sent somewhere else, eg for presentation by some other kind of console protocol b. telnetd is often not installed, or when it is it may not support the -L parameter for a custom login program c. klunky. d. hasn't anyone heard of apt-get install termnetd? :-) |
From: Jeff D. <jd...@ad...> - 2004-01-23 14:20:49
|
On Fri, Jan 23, 2004 at 02:26:39PM +1030, Dan Shearer wrote: > In the case of UML it does no > authentication, just relays characters between file descriptors. No. > The login program, which is receiving data from the master side of > the pty that telnetd opened, sends the data back through this pipe And no. port_helper passes the actual file descriptor back to UML through the unix socket on fd 3. Then, UML receives characters directly from telnetd without port_helper having to relay them. Otherwise, this is pretty good. > d. hasn't anyone heard of apt-get install termnetd? :-) I never heard of termnetd. I think it's less likely to be installed on a given system than telnetd though :-) If UML were to use it, it would have to write out a config file and tell termnetd to use it. That's not horrible, but it is less convenient than being able to put everything on the command line. Jeff |
From: Dan S. <da...@sh...> - 2004-01-26 18:47:05
|
On Fri, Jan 23, 2004 at 09:43:20AM -0500, Jeff Dike wrote: > > The login program, which is receiving data from the master side of > > the pty that telnetd opened, sends the data back through this pipe > > And no. port_helper passes the actual file descriptor back to UML through > the unix socket on fd 3. Then, UML receives characters directly from telnetd > without port_helper having to relay them. Got it now. Here is a patch to port-helper that might help others. > Otherwise, this is pretty good. You mean apart from the fact that I missed the point entirely. Another fumbling newbie question: why can't we just have the fd for the unix socket for xterm connected before xterm is exec'd? Then there would be no need for open_socket in port-helper. I'm sure there's an obvious reason. -- Dan Shearer da...@sh... --- port-helper.c.orig +++ port-helper.c @@ -1,3 +1,15 @@ +/* port-helper + +Used by the port and xterm console channels for User Mode Linux. + +Tells UML "here is a file descriptor for my stdin as given to me by +xterm or telnetd". Once UML has that (with os_rcv_fd()) UML opens it +for read and write, and the console is functional. + +(c) Jeff Dike 2002-2004 + +*/ + #include <stdio.h> #include <stdlib.h> #include <signal.h> @@ -8,8 +20,17 @@ #include <sys/un.h> #include <sys/uio.h> +/* pass the fd over an fd that is already connected to a socket */ static void send_fd(int fd, int target) { + + /* File descriptors are specific to a process and normally only + sharable with another process by inheritence with fork(). The + alternative is to use sendmsg with a special flag that says + "I'm knowingly giving another process information from my private + file descriptor table" (SCM_RIGHTS) + */ + char anc[CMSG_SPACE(sizeof(fd))]; struct msghdr msg; struct cmsghdr *cmsg; @@ -42,6 +63,8 @@ } } +/* for xterm we don't have an open socket, we only have the name + of a file used as a Unix socket by UML. So we need to open it. */ static int open_socket(char *name) { struct sockaddr_un sock; @@ -74,12 +97,17 @@ { int fd; - if((argc > 1) && !strcmp(argv[1], "-uml-socket")) fd = open_socket(argv[2]); - else fd = 3; + if((argc > 1) && !strcmp(argv[1], "-uml-socket")) { + /* inherited a filename not an open fd */ + fd = open_socket(argv[2]); + } else { + /* inherited fd of the listening TCP socket */ + fd = 3; + } signal(SIGHUP, SIG_IGN); if(ioctl(0, TIOCNOTTY, 0) < 0) - perror("TIOCNOTTY failed"); + perror("TIOCNOTTY failed in port-helper, check UML's exec call for xterm or telnetd"); send_fd(0, fd); pause(); return(0); |
From: Jeff D. <jd...@ad...> - 2004-01-25 17:28:57
|
da...@sh... said: > Another fumbling newbie question: why can't we just have the fd for > the unix socket for xterm connected before xterm is exec'd? Then there > would be no need for open_socket in port-helper. I'm sure there's an > obvious reason. I think that's just paranoia. IIRC, I was more confident about command-line switches getting through xterm than open file descriptors. I think I needed to pass an open file descriptor through telnetd because there is no way to influence the command line of the -L login program. Thanks for the patch. Jeff |
From: Dan S. <da...@sh...> - 2004-01-26 01:58:29
|
On Sat, Jan 24, 2004 at 01:20:21PM -0500, Jeff Dike wrote: > da...@sh... said: > > Another fumbling newbie question: why can't we just have the fd for > > the unix socket for xterm connected before xterm is exec'd? Then there > > would be no need for open_socket in port-helper. I'm sure there's an > > obvious reason. > > I think that's just paranoia. IIRC, I was more confident about command-line > switches getting through xterm than open file descriptors. I think I needed > to pass an open file descriptor through telnetd because there is no way to > influence the command line of the -L login program. Right, I wondered if it might be because xterm support came long before telentd. Now that you've seen telnetd working reliably, would you accept xterm using fd passing too provided testing went ok? Factoring out code and one less thing to worry about when porting UML to other types of OS. -- Dan Shearer da...@sh... |
From: Jeff D. <jd...@ad...> - 2004-01-26 17:51:14
|
da...@sh... said: > Now that you've seen telnetd working reliably, would you accept xterm > using fd passing too provided testing went ok? Factoring out code and > one less thing to worry about when porting UML to other types of OS. There is that, but the xterm man page guarantees that the arguments will be passed through to the subprocess and makes no such guarantees about file descriptors. So, I'd just as soon leave things as they are. This seems to maximize the likelihood that they will continue to work. Jeff |