Vmware Esx Server - how to connect a serial port to a virtual machine

Some softwares running on virtual machines need to connect to the serial port (COM) to communicate with a serial device, but Esx server doesn't share the physical serial port to the virtual machines. How to do?
In my case I had the need to connect a proprietary software running on a windows virtual machine (living into an Esx server) to a led display managed through the serial port.

This is what I did:
I physically connected the led display to a the serial port of a unix server (/dev/ttyS0). I used ser2net to bridge the serial port over a network port (tcp/1001) and I connected the display management tool to the ethernet port.
Serial over ethernet configuration
On the linux host:
First some checks: are serial ports connected to the system and well configured?
dmesg | grep tty ttyS0 at 0x03f8 (irq = 4) is a 16550A ttyS1 at 0x02f8 (irq = 3) is a 16550A setserial -g /dev/ttyS[01] /dev/ttyS0, UART: 16550A, Port: 0x03f8, IRQ: 4 /dev/ttyS1, UART: 16550A, Port: 0x02f8, IRQ: 3
To test if the serial port was working as expected I connected it to the serial management port of a Cisco device and I connected to the terminal through minicom
apt-get install minicom
then I did
1) minicom -s, to enter configuration mode: it opens a text-based menu. Note: Use "ENTER" to exit any menus except the main menu.
2) under "Serial Port Setup" mine was set to default /dev/ttyS0 and 38400. I had to manually change it to 9600. Remember to hit ENTER to exit, do NOT try to use "Q" to "Quit"
3) under "Modem and Dialing" remove the "Init String". Anything in this field will be sent to the device when you connect.
4) from the main menu use "Save setup to DFL" to create a new default config file for minicom.
(thanks anonymous)
running
minicom
I could see the Cisco command prompt, so the port was working as expected and I went forward to the serial bridging over the ethernet.
I tried several software but ser2net is absolutely the best because it allows a fine tuning of the com port parameters.
Ser2net is available on the debian repository but I preferred to compile it from its latest release (at the time of writing is 2.7) and it can be installed as common with configure make and make install.
x3400:~# which ser2net /usr/local/sbin/ser2net
Unfortunately the documentation isn't so easy and ready to go: it lacks examples.
This is its configuration file:
x3400:~# cat /etc/ser2net.conf # # This is an example configuration file for ser2net. It has the following # format: # <TCP port>:<state>:<timeout>:<device>:<options> # TCP port # Name or number of the TCP/IP port to accept con- # nections from for this device. A port number may # be of the form [host,]port, such as 127.0.0.1,2000 # or localhost,2000. If this is specified, it will # only bind to the IP address specified. Otherwise # it will bind to all the ports on the machine. # # state Either raw or rawlp or telnet or off. off disables # the port from accepting connections. It can be # turned on later from the control port. raw enables # the port and transfers all data as-is between the # port and the long. rawlp enables the port and # transfers all input data to device, device is open # without any termios setting. It allow to use # /dev/lpX devices and printers connected to them. # telnet enables the port and runs the telnet proto- # col on the port to set up telnet parameters. This # is most useful for using telnet. # # timeout # The time (in seconds) before the port will be dis- # connected if there is no activity on it. A zero # value disables this function. # # device The name of the device to connect to. This # must be in the form of /dev/<device>. # # options # Sets operational parameters for the serial port. # Options 300, 1200, 2400, 4800, 9600, 19200, 38400, # 57600, 115200 set the various baud rates. EVEN, # ODD, NONE set the parity. 1STOPBIT, 2STOPBITS set # the number of stop bits. 7DATABITS, 8DATABITS set # the number of data bits. [-]XONXOFF turns on (- # off) XON/XOFF support. [-]RTSCTS turns on (- off) # hardware flow control, [-]LOCAL turns off (- on) # monitoring of the modem lines, and # [-]HANGUP_WHEN_DONE turns on (- off) lowering the # modem control lines when the connection is done. # NOBREAK disables automatic setting of the break # setting of the serial port. # The "remctl" option allow remote control (ala RFC # 2217) of serial-port configuration. A banner name # may also be specified, that banner will be printed # for the line. If no banner is given, then no # banner is printed. # The tw, tr, and tb options take a tracefile name ( # specified in TRACEFILE that will take all traced data. # tw is data written to the device, tr is data read from # the device, and tb is both. # # or... # BANNER:<banner name>:banner # This will create a banner, if the banner name is given in the # options of a line, that banner will be printed. This takes the # standard "C" \x characters (\r is carraige return, \n is newline, # etc.). It also accepts \d, which prints the device name, \p, # which prints the TCP port number, and \s which prints the serial # parameters (eg 9600N81). Banners can span lines if the last # character on a line is '\'. Note that you *must* use \r\n to # start a new line. # # TRACEFILE:<name>:filename # This specifies a filename to trace output into, as tw:/tmp/trace1. # This takes a large number of escape sequences, see the man page # for details on these options. # # Note that the same device can be listed multiple times under different # ports, this allows the same serial port to have both telnet and raw # protocols. BANNER:banner1:Welcome to ser2net TCP port \p device \d\r\n\ second line \ third line\r\n BANNER:banner2:this is ser2net TCP port \p device \d\r\n\ second line \ third line\r\n BANNER:banner3:this is ser2net TCP port \p device \d serial parms \s\r\n TRACEFILE:tw1:/tmp/tw-\p-\Y-\M-\D-\H:\i:\s.\U TRACEFILE:tr1:/tmp/tr-\p-\Y-\M-\D-\H:\i:\s.\U
1001:raw:600:/dev/ttyS0:9600 EVEN #2001:raw:600:/dev/ttyS0:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS #2002:raw:600:/dev/ttyS1:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS #2003:raw:5:/dev/ttyS2:9600 #2004:raw:5:/dev/ttyS3:115200 #2005:raw:5:/dev/ttyS4:9600 #2006:raw:5:/dev/ttyS5:9600 #2007:raw:5:/dev/ttyS6:9600 tw=tw1 tr=tr1 #3001:telnet:0:/dev/ttyS0:19200 remctl banner1 #3011:telnet:3:/dev/ttyS0:19200 banner2 #3002:telnet:0:/dev/ttyS1:9600 #3003:telnet:0:/dev/ttyS2:9600 banner3 #3004:telnet:0:/dev/ttyS3:115200 #3005:telnet:0:/dev/ttyS4:9600 #3006:telnet:0:/dev/ttyS5:9600 #3007:telnet:0:/dev/ttyS6:9600 #5001:rawlp:10:/dev/lp0
x3400:~# cat /etc/ser2net.conf # # This is an example configuration file for ser2net. It has the following # format: # <TCP port>:<state>:<timeout>:<device>:<options> # TCP port # Name or number of the TCP/IP port to accept con- # nections from for this device. A port number may # be of the form [host,]port, such as 127.0.0.1,2000 # or localhost,2000. If this is specified, it will # only bind to the IP address specified. Otherwise # it will bind to all the ports on the machine. # # state Either raw or rawlp or telnet or off. off disables # the port from accepting connections. It can be # turned on later from the control port. raw enables # the port and transfers all data as-is between the # port and the long. rawlp enables the port and # transfers all input data to device, device is open # without any termios setting. It allow to use # /dev/lpX devices and printers connected to them. # telnet enables the port and runs the telnet proto- # col on the port to set up telnet parameters. This # is most useful for using telnet. # # timeout # The time (in seconds) before the port will be dis- # connected if there is no activity on it. A zero # value disables this function. # # device The name of the device to connect to. This # must be in the form of /dev/<device>. # # options # Sets operational parameters for the serial port. # Options 300, 1200, 2400, 4800, 9600, 19200, 38400, # 57600, 115200 set the various baud rates. EVEN, # ODD, NONE set the parity. 1STOPBIT, 2STOPBITS set # the number of stop bits. 7DATABITS, 8DATABITS set # the number of data bits. [-]XONXOFF turns on (- # off) XON/XOFF support. [-]RTSCTS turns on (- off) # hardware flow control, [-]LOCAL turns off (- on) # monitoring of the modem lines, and # [-]HANGUP_WHEN_DONE turns on (- off) lowering the # modem control lines when the connection is done. # NOBREAK disables automatic setting of the break # setting of the serial port. # The "remctl" option allow remote control (ala RFC # 2217) of serial-port configuration. A banner name # may also be specified, that banner will be printed # for the line. If no banner is given, then no # banner is printed. # The tw, tr, and tb options take a tracefile name ( # specified in TRACEFILE that will take all traced data. # tw is data written to the device, tr is data read from # the device, and tb is both. # # or... # BANNER:<banner name>:banner # This will create a banner, if the banner name is given in the # options of a line, that banner will be printed. This takes the # standard "C" \x characters (\r is carraige return, \n is newline, # etc.). It also accepts \d, which prints the device name, \p, # which prints the TCP port number, and \s which prints the serial # parameters (eg 9600N81). Banners can span lines if the last # character on a line is '\'. Note that you *must* use \r\n to # start a new line. # # TRACEFILE:<name>:filename # This specifies a filename to trace output into, as tw:/tmp/trace1. # This takes a large number of escape sequences, see the man page # for details on these options. # # Note that the same device can be listed multiple times under different # ports, this allows the same serial port to have both telnet and raw # protocols. BANNER:banner1:Welcome to ser2net TCP port \p device \d\r\n\ second line \ third line\r\n BANNER:banner2:this is ser2net TCP port \p device \d\r\n\ second line \ third line\r\n BANNER:banner3:this is ser2net TCP port \p device \d serial parms \s\r\n TRACEFILE:tw1:/tmp/tw-\p-\Y-\M-\D-\H:\i:\s.\U TRACEFILE:tr1:/tmp/tr-\p-\Y-\M-\D-\H:\i:\s.\U 1001:raw:600:/dev/ttyS0:9600 EVEN #2001:raw:600:/dev/ttyS0:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS #2002:raw:600:/dev/ttyS1:9600 NONE 1STOPBIT 8DATABITS XONXOFF LOCAL -RTSCTS #2003:raw:5:/dev/ttyS2:9600 #2004:raw:5:/dev/ttyS3:115200 #2005:raw:5:/dev/ttyS4:9600 #2006:raw:5:/dev/ttyS5:9600 #2007:raw:5:/dev/ttyS6:9600 tw=tw1 tr=tr1 #3001:telnet:0:/dev/ttyS0:19200 remctl banner1 #3011:telnet:3:/dev/ttyS0:19200 banner2 #3002:telnet:0:/dev/ttyS1:9600 #3003:telnet:0:/dev/ttyS2:9600 banner3 #3004:telnet:0:/dev/ttyS3:115200 #3005:telnet:0:/dev/ttyS4:9600 #3006:telnet:0:/dev/ttyS5:9600 #3007:telnet:0:/dev/ttyS6:9600 #5001:rawlp:10:/dev/lp0
This row
1001:raw:600:/dev/ttyS0:9600 EVEN
means that the serial port /dev/ttyS0 (COM1 in windows) will be connected raw to the tcp/1001 port. 600 in the timeout, 9600 is the baud rate. EVEN sets the parity: generally is set to NONE but in my case I spent several hours on tests before to understand that was the problem avoiding me to communicate with the proprietary software (of course there wasn't a word about that in the documentation)
Ser2net can be launched from a console:
ser2net -d
Using netstat and fuser I can double check if ser2net is listening on the given port
x3400:~# netstat -ltpn Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:2049 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:47556 0.0.0.0:* LISTEN 3381/rpc.mountd tcp 0 0 127.0.0.1:709 0.0.0.0:* LISTEN 3501/famd tcp 0 0 0.0.0.0:1001 0.0.0.0:* LISTEN 8704/ser2net tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 2804/portmap tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 8313/vmware-convert tcp 0 0 0.0.0.0:113 0.0.0.0:* LISTEN 3392/inetd tcp 0 0 0.0.0.0:49138 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3186/sshd tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 3314/cupsd tcp 0 0 0.0.0.0:43895 0.0.0.0:* LISTEN 2816/rpc.statd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3462/master tcp 0 0 127.0.0.1:6010 0.0.0.0:* LISTEN 8687/4 tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 8313/vmware-convert tcp 0 0 0.0.0.0:3551 0.0.0.0:* LISTEN 3594/apcupsd tcp6 0 0 :::139 :::* LISTEN 3478/smbd tcp6 0 0 :::5900 :::* LISTEN 6231/vino-server tcp6 0 0 :::80 :::* LISTEN 8313/vmware-convert tcp6 0 0 :::22 :::* LISTEN 3186/sshd tcp6 0 0 ::1:6010 :::* LISTEN 8687/4 tcp6 0 0 :::443 :::* LISTEN 8313/vmware-convert tcp6 0 0 :::445 :::* LISTEN 3478/smbd
OR
x3400:~# fuser -n tcp 1001 1001/tcp: 8704 x3400:~# ps aux | grep 8704 root 8704 0.0 0.0 6008 568 pts/1 S+ 10:50 0:00 ser2net -d
Lucky me the proprietary tool to manage the led display is capable to connect over the network so, after discovering the "even parity thing" I successfully connected to the ethernet port and then to the led display.

... but I was curious and I tried to make a real serial over ethernet bridge: physical serial (host1) -> ethernet -> virtual serial (virtual machine)
I used com0com a tool for windows (* linux version) and its related tools : I read com0com documentation and hub4com the readme.txt (com2tcp, hub4com) included and I was capable to make the bridge but my display management application didn't connect .... probably due to the parity issue.
Starting ser2net as a service at boot
The compiled version of ser2net obviously doesn't set itself as a daemon to be started at boot time, so I added it manually. (The debian package should already provide it)
vim /etc/init.d/serial2network
#! /bin/bash
### BEGIN INIT INFO
# Provides: ser2net
# Required-Start:
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 1
# Short-Description: serial over ethernet
### END INIT INFO
kill_pid() {
PID=$(pidof "$1")
if [ "$PID" != "" ]
then
# echo "PID "$PID
pidof "$1" | xargs kill
fi
}
if [ ! -e "/usr/local/sbin/ser2net" ]
then
echo "ser2net is not installed"
exit 1
fi
if [ ! -e "/etc/ser2net.conf" ]
then
echo "ser2net config file is missing"
exit 1
fi
case "$1" in
start)
echo "Stopping previous ser2net..."
echo
kill_pid "ser2net"
echo "Starting ser2net"
/usr/local/sbin/ser2net
if [ "$?" == "0" ]
then
echo "done"
else
echo "not started"
fi
;;
stop)
echo "Stopping ser2net"
kill_pid ser2net
echo "done"
;;
*)
echo "Usage: /etc/init.d/serial2network {start|stop}"
exit 1
esac
exit 0
and finally I added it to the starting services
x3400:~# update-rc.d serial2network defaults Adding system startup for /etc/init.d/serial2network ... /etc/rc0.d/K20serial2network -> ../init.d/serial2network /etc/rc1.d/K20serial2network -> ../init.d/serial2network /etc/rc6.d/K20serial2network -> ../init.d/serial2network /etc/rc2.d/S20serial2network -> ../init.d/serial2network /etc/rc3.d/S20serial2network -> ../init.d/serial2network /etc/rc4.d/S20serial2network -> ../init.d/serial2network /etc/rc5.d/S20serial2network -> ../init.d/serial2network
-----------------
Just a note for windows users: during my never ending tests I found this tool Virtual Serial Port Driver. It comes as a trial version expiring after a couple of weeks. I tried it and it worked smoothly.
References:
serialproxy: it works and it's easy to set up but it lacks the possibility to configure the serial parameters (in my case it turned to be a must!)
* remserial: another software similiar to ser2net (not tried). It seems good to perform a serial bridge over the ethernet for 2 unix hosts. I mean: physical serial (host1) -> ethernet -> virtual serial (host2)
- dam's blog
- 1337 reads

Post new comment