A Virtual Serial Line


We are going to round out this chapter with another example of the two UML instances communicating over simulated hardware. This time, we will use a virtual serial line running between them to log in from one to the other.

This serial line will be constructed from a host pseudo-terminal, namely, a UNIX 98 pts device. Pseudo-terminals on UNIX are pipes whatever goes in one end comes out the other, possibly with some processing in between, such as line editing. This processing distinguishes pseudo-terminals from normal UNIX pipes. The end that's opened first is the pty end, and it's the master sidethe device doesn't really exist until this side is opened. So, the instance to which we are going to log in will open the master side of the device, and later, the slave side will be opened by the other instance when we log in over it.

We are going to make both ends of the device appear inside the instances as normal, hardwired terminals. One instance is going to run a getty on it, and we will run a screen session inside the other instance attached to its terminal.

To get started, we need to identify an unused terminal in both instances. There are two ways to do thisread /etc/inittab to find the first terminal that has no getty running on it, or run ps to discover the same thing. The relevant section of inittab looks like this:

# /sbin/getty invocations for the runlevels. # # The "id" field MUST be the same as the last # characters of the device (after "tty"). # # Format: #  <id>:<runlevels>:<action>:<process> 0:2345:respawn:/sbin/getty 38400 tty0 1:2345:respawn:/sbin/getty 38400 tty1 2:2345:respawn:/sbin/getty 38400 tty2 3:2345:respawn:/sbin/getty 38400 tty3 4:2345:respawn:/sbin/getty 38400 tty4 5:2345:respawn:/sbin/getty 38400 tty5 6:2345:respawn:/sbin/getty 38400 tty6 7:2345:respawn:/sbin/getty 38400 tty7 c:2345:respawn:/sbin/getty 38400 ttyS0


It appears that tty8 is unused. ps confirms this:

UML1# ps uax | grep getty root       153  0.0  0.3  1084  444 tty1    S   14:07    0:00      /sbin/getty 38400 tty1 root       154  0.0  0.3  1088  448 tty2    S   14:07    0:00      /sbin/getty 38400 tty2 root       155  0.0  0.3  1084  444 tty3    S   14:07    0:00      /sbin/getty 38400 tty3 root       156  0.0  0.3  1088  448 tty4    S   14:07    0:00      /sbin/getty 38400 tty4 root       157  0.0  0.3  1088  452 tty5    S   14:07    0:00      /sbin/getty 38400 tty5 root       158  0.0  0.3  1088  452 tty6    S   14:07    0:00      /sbin/getty 38400 tty6 root       159  0.0  0.3  1088  452 tty7    S   14:07    0:00      /sbin/getty 38400 tty7 root       160  0.0  0.3  1084  444 ttyS0   S   14:07    0:00      /sbin/getty 38400 ttyS0


This is the same on both instances, as you would expect, so we will use tty8 as the serial line on both.

First we need to plug in a properly configured tty8 to the master UML instance, the one to which we will be logging in. We do this with uml_mconsole on the host, configuring con8, which is the mconsole name for the device that is tty8 inside UML:

host% uml_mconsole debian2 config con8=pts OK


Now, the master UML instance has a tty8, and we need to know which pseudo-terminal on the host it allocated so that we can connect the other instance's tty8 to the other end of it. Right now, it's not connected to anything, as it waits until the device is opened before allocating a host terminal. So, to get something to open it, we'll run getty on it:

UML2# /sbin/getty 38400 tty8


Now we need to know what the other end of the pts device is, since that's determined dynamically for these devices:

host% uml_mconsole debian2 config con8 OK pts:/dev/pts/28


This tells us how to configure con8 on the slave UML:

host% uml_mconsole debian1 config con8=tty:/dev/pts/28 OK


Here we are using tty instead of pts as the device type because the processes of opening the two sides of the device are slightly different, and we are opening the slave side here.

This will just sit there, so we now go to the slave UML instance and attach screen to its tty8 :

UML1# screen /dev/tty8


Figure 4.3 shows what we have constructed. The two UML consoles are connected to opposite ends of the host's /dev/pts/28 and communicate through it. From inside the UML instances, it appears that the two UML /dev/tty8 devices are connected directly to each other.

Figure 4.3. A virtual serial line. The two UML /dev/tty8 devices are connected to the host's /dev/pts/28 pseudo-terminal, the master side connected to the UML instance that will be logged into and the slave side connected to the UML instance that will be logging in. The master side is connected to the UML instance's getty, login, and bash as the login proceeds. On the other side, screen is connected to the UML instance's /dev/tty8, which is attached to the slave side of the host pseudoterminal. The solid lines show the actual flow of data through the UML consoles and the host pseudo-terminal. The dashed line shows the flow of data apparent to the UML users, who see the two UML consoles directly connected to each other.


Now you should see a login prompt in the screen session. Log in and determine that it really is the other instance. During the examples in this chapter, we've copied different things into /tmp, assigned different IP addresses to their network interfaces, and played with their routing tables, so this should not be hard to verify.

Once you log out, you'll notice that the getty exits back to the shell, and you get no login prompt in the screen session. This is the purpose of the respawn on the getty lines in /etc/inittab. If you wrapped the getty command in an infinite loop, you would be doing a passable imitation of init. However, we will just exit the screen session (^A K ) to get back to the prompt in the other instance.

We are done with these UMLs, so you can just halt them and remove their COW files if you want to reclaim whatever disk space they consumed.

The point of this exercise was not to demonstrate that two UML instances can be used to simulate a serial linephysical serial lines are not hard to come by and not that hard to set up. Rather, it was to demonstrate how easily a virtual device on the host can be pressed into service as a physical device inside UML. A serial line is probably the simplest example of this, which is why I used it. Out of the box, UML can emulate many other sorts of hardware, and for other types, it is fairly simple to write a UML driver that emulates the device. Other examples include using shared memory on the host to emulate a device with memory-mapped I/O, which some embedded systems developers have done, and using shared memory to emulate a cluster interconnect, with multiple UML instances on the host being the emulated cluster.

More prosaic, and more common, is the need to emulate a network environment for purposes such as setting it up, reconfiguring it, and testing fault handling. We saw an example of testing failover from a failed network to a hot spare network. This only scratches the surface of what can be done with a virtual network. A network of UMLs can be configured in any way that a physical network can and a lot of ways that a physical network can't, making UML an ideal way to set up, develop, and test networks before physically building them.



User Mode Linux
User Mode Linux
ISBN: 0131865056
EAN: 2147483647
Year: N/A
Pages: 116
Authors: Jeff Dike

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net