Skip to content

msantos/evum

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

45 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spawn Linux VMs as Erlang processes in the Erlang VM.

evum makes a Linux virtual machine into an Erlang actor. While the Linux VM has its own state like any other process (memory, system processes, disk), all I/O with the outside world is sent as messages through the Erlang VM (currently working: network, system console).

REQUIREMENTS

sudo apt-get install user-mode-linux

TODO

  • persistent state mounted as filesystem

EXAMPLE

Quick Start

  • Download and create a buildroot instance

      1> {ok, Ref} = evm:create([
              {label, test1},     % Label identifying this vm
              {dist, buildroot}   % Linux distribution image, defined in priv/evm.cfg
              ]).
      {ok,<0.60.0>}
    
      2> flush(). % See the boot messages
    
      3> evum:send(test1, "hostname").
      4> flush().
      Shell got <<"evm">>
      ok
    
  • Download and create an OpenWRT instance with network access

Set the network configuration for your VM in priv/evm.cfg:

{network, [
    {home, [
        {base_ip, "192.168.213."},
            {first_ip, 92},
            {netmask, "255.255.255.0"},
            {gw, "192.168.213.1"}
    ]}
    ]}.

Create the OpenWRT VM:

1> {ok, Ref} = evm:create([
        {label, test2},     % Label for this vm
        {dist, openwrt},    % Defined in priv/evm.cfg
        {net, coffeeshop}   % Set up networking: see priv/evm.cfg
        ]).
{ok,<0.60.0>}

From another host (NOTE: will not work from the system running evum), telnet to the IP address of the OpenWRT VM:

telnet 192.168.213.92 # or: nc -t 192.168.213.92 22

Run some commands in the VM. All the network data is proxied through Erlang:

opkg update # may need to adjust /etc/resolv.conf first
opkg install erlang
erl

Using the Host OS

% Start the network
1> {ok,Switch} = evum_switch:start().
{ok,<0.43.0>}

% Start the system console server
2> evum_ctl:start(Switch).
{ok,<0.58.0>}

% Start a Linux VM
3> {ok,R1} = evum:start().
{ok,<0.61.0>}

% And another VM ...
3> {ok,R2} = evum:start().
4ok,<0.64.0>}

% One more VM ...
5> {ok,R3} = evum:start().
{ok,<0.67.0>}

% See the Linux boot messages
6> flush().

% Set up the network interfaces
7> evum:ifconfig(R1, {"192.168.213.92","255.255.255.0","192.168.213.1"}).

8> evum:ifconfig(R2, {"192.168.213.93","255.255.255.0","192.168.213.1"}).

9> evum:ifconfig(R3, {"192.168.213.94","255.255.255.0","192.168.213.1"}).

10> evum:send(R1, "ifconfig -a").
<<"root@(none):/# ifconfig -a">>

11> flush().
Shell got <<"eth0      Link encap:Ethernet  HWaddr 00:21:5d:7c:11:11  ">>
Shell got <<"          inet addr:192.168.213.92  Bcast:192.168.213.255  Mask:255.255.255.0">>
Shell got <<"          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1">>
Shell got <<"          RX packets:0 errors:0 dropped:0 overruns:0 frame:0">>
Shell got <<"          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0">>
Shell got <<"          collisions:0 txqueuelen:1000 ">>
Shell got <<"          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)">>
Shell got <<"          Interrupt:5 ">>
Shell got <<>>
Shell got <<"lo        Link encap:Local Loopback  ">>
Shell got <<"          LOOPBACK  MTU:16436  Metric:1">>
Shell got <<"          RX packets:0 errors:0 dropped:0 overruns:0 frame:0">>
Shell got <<"          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0">>
Shell got <<"          collisions:0 txqueuelen:0 ">>
Shell got <<"          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)">>
Shell got <<>>

% Ping something, so our fake switch can learn of the VM's prescence
12> evum:ping(R1, {192,168,213,7}).
13> evum:ping(R2, {192,168,213,7}).
14> evum:ping(R3, {192,168,213,7}).

8> flush().
Shell got <<"PING 192.168.213.7 (192.168.213.7) 56(84) bytes of data.">>
Shell got <<"64 bytes from 192.168.213.7: icmp_seq=1 ttl=64 time=53.9 ms">>
Shell got <<>>
Shell got <<"--- 192.168.213.7 ping statistics ---">>
Shell got <<"1 packets transmitted, 1 received, 0% packet loss, time 0ms">>
Shell got <<"rtt min/avg/max/mdev = 53.918/53.918/53.918/0.000 ms">>

% start up a shell (of sorts) on a port
10> evum:send(R, "socat tcp-l:7777,reuseaddr,fork system:'/bin/bash',stderr &").
<<"root@(none):/# socat tcp-l:7777,reuseaddr,fork system:'/bin/bash',stderr &">>

From another host:

$ nc 192.168.213.92 7777
cat /proc/cpuinfo
processor       : 0
vendor_id       : User Mode Linux
model name      : UML
mode            : skas
host            : Linux rst 2.6.32-26-generic #48-Ubuntu SMP Wed Nov 24 09:00:03 UTC 2010 i686
bogomips        : 1468.00

SCREENSHOT: Erlang in Erlang!

root@OpenWrt:/tmp# opkg install erlang
Installing erlang (R13A-1) to root...
Downloading http://downloads.openwrt.org/backfire/10.03/x86/packages/erlang_R13A-1_x86.ipk.
Installing libncurses (5.7-2) to root...
Downloading http://downloads.openwrt.org/backfire/10.03/x86/packages/libncurses_5.7-2_x86.ipk.
Installing librt (0.9.30.1-42) to root...
Downloading http://downloads.openwrt.org/backfire/10.03/x86/packages/librt_0.9.30.1-42_x86.ipk.
Configuring libncurses.
Configuring librt.
Configuring erlang.
root@OpenWrt:/tmp# erl
Erlang R13A (erts-5.7) [source] [rq:1] [kernel-poll:false]

Eshell V5.7  (abort with ^G)
1> spawn(io, format, ["Erlang process spawned in an Erlang VM in a Linux VM in an Erlang process in an Erlang VM~n"]).
Erlang process spawned in an Erlang VM in a Linux VM in an Erlang process in an Erlang VM
<0.35.0>
2>

About

["Linux VM", ["Erlang Process", ["Erlang VM"]]].

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages