Hi,
I think I have some good news for you regarding your nested virtualization case! It might even work on Windows but I have not tested it.
My setup involved a hardware host with Ubuntu 21.04 and two VirtualBox 6.1 VM (whatever version Ubuntu 21.04 comes with) running Ubuntu Server 20.04.3. Each VBox VM was configured with a networking setup to use Bridged Adapter using the real ethernet NIC on the physical host and enabled Promiscuous Mode equal to "Allow All" which is key and I see you had it enabled.
Now the key thing inside of the two Ubuntu VMs was to set up a so-called external bridge so that each OSv instance could use an IP from the same subnet the physical host is attached to. Under the
scripts directory, there is a script called
setup-external-bridge.sh (please see the wiki
https://github.com/cloudius-systems/osv/wiki/Running-OSv-on-Firecracker#networking which for some details), which takes the name of the VM NIC as a 1st argument and the name of the bridge (the default is virbr1) as the 2nd. In essence, this script creates another bridge within a VM that both Ubuntu guest and then OSv sub-guest can belong to and also allows for traffic to flow through all levels up and down to the physical host. Here is how the Ubuntu VM interfaces look like:
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 08:00:27:1c:68:ac txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
virbr0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 192.168.122.1 netmask 255.255.255.0 broadcast 192.168.122.255
ether 52:54:00:42:32:17 txqueuelen 1000 (Ethernet)
virbr1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.118 netmask 255.255.255.0 broadcast 192.168.1.255
ether 08:00:27:1c:68:ac txqueuelen 1000 (Ethernet)
Please note the guest "lost" an IP on enp0s3 NIC and "switched" to an IP 192.168.1.118 attached to virb1. In my case, the other Ubuntu VM had an address 192.168.1.119 and both of those came from DHCP server on my local network.
Now on each Ubuntu VM I would run an OSv instance using a shell script runOSv_bridged.sh based on the output from "./scripts/run.py -k -n -b virbr1 --mac 52:54:00:12:34:01 --dry-run" (-k makes it easier to pass arguments):
COMMAND="$1"
qemu-system-x86_64 \
-m 256M \
-smp 1 \
-vnc :1 \
-gdb tcp::1234,server,nowait \
-kernel ./kernel.elf \
-append "--rootfs=rofs $COMMAND" \
-device virtio-blk-pci,id=blk0,drive=hd0,scsi=off \
-drive file=/home/wkozaczuk/usr.img,if=none,id=hd0,cache=none,aio=native \
-netdev bridge,id=hn0,br=virbr1,helper=/usr/lib/qemu/qemu-bridge-helper \
-device virtio-net-pci,netdev=hn0,id=nic0,mac=52:54:00:12:34:01 \
-device virtio-rng-pci \
-chardev stdio,mux=on,id=stdio,signal=off \
-mon chardev=stdio,mode=readline \
-device isa-serial,chardev=stdio
To test the communication between the OSv instances I used the cli app built like so:
./scripts/build image=cli fs=rofs
and then run it on VM1 like so:
sudo ./runOSv_bridged.sh "--ip=eth0,192.168.1.120,255.255.255.0 --defaultgw=192.168.1.254 --nameserver=192.168.1.254 /cli -a
http://192.168.1.121:8000"
and then run it on VM2 like so:
sudo ./runOSv_bridged.sh "--ip=eth0,192.168.1.121,255.255.255.0 --defaultgw=192.168.1.254 --nameserver=192.168.1.254 /cli -a
http://192.168.1.120:8000"
The full output here:
"
sudo ./runOSv_bridged.sh "--ip=eth0,192.168.1.120,255.255.255.0 --defaultgw=192.168.1.254 --nameserver=192.168.1.254 /cli -a
http://192.168.1.121:8000"
[sudo] password for wkozaczuk:
OSv v0.56.0-5-g247d6837
eth0: 192.168.1.120
Booted up in 0.00 ms
Rest API server running on port 8000
/# dmesg
1 CPUs detected
Firmware vendor: SeaBIOS
bsd: initializing - done
VFS: mounting ramfs at /
VFS: mounting devfs at /dev
net: initializing - done
vga: Add VGA device instance
eth0: ethernet address: 52:54:00:12:34:02
virtio-blk: Add blk device instances 0 as vblk0, devsize=20144128
random: virtio-rng registered as a source.
random: <Software, Yarrow> initialized
VFS: unmounting /dev
VFS: mounting rofs at /rofs
VFS: mounting devfs at /dev
VFS: mounting procfs at /proc
VFS: mounting sysfs at /sys
VFS: mounting ramfs at /tmp
Running from /init/30-auto-03: /libhttpserver-api.so &!
random: device unblocked.
/usr/lib/libbsd.so.0: ignoring missing symbol fopencookie
/usr/lib/libbsd.so.0: ignoring missing symbol warnx
/usr/lib/libbsd.so.0: ignoring missing symbol sigpending
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_api.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_app.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_env.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_file.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_fs.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_hardware.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_network.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_os.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_trace.so
sysconf(): stubbed for parameter 43
/#
sudo ./runOSv_bridged.sh "--ip=eth0,192.168.1.121,255.255.255.0 --defaultgw=192.168.1.254 --nameserver=192.168.1.254 /cli -a
http://192.168.1.120:8000"
OSv v0.56.0-5-g247d6837
eth0: 192.168.1.121
Booted up in 0.00 ms
Rest API server running on port 8000
/# dmesg
1 CPUs detected
Firmware vendor: SeaBIOS
bsd: initializing - done
VFS: mounting ramfs at /
VFS: mounting devfs at /dev
net: initializing - done
vga: Add VGA device instance
eth0: ethernet address: 52:54:00:12:34:01
virtio-blk: Add blk device instances 0 as vblk0, devsize=20144128
random: virtio-rng registered as a source.
random: <Software, Yarrow> initialized
VFS: unmounting /dev
VFS: mounting rofs at /rofs
VFS: mounting devfs at /dev
VFS: mounting procfs at /proc
VFS: mounting sysfs at /sys
VFS: mounting ramfs at /tmp
Running from /init/30-auto-03: /libhttpserver-api.so &!
/usr/lib/libbsd.so.0: ignoring missing symbol fopencookie
/usr/lib/libbsd.so.0: ignoring missing symbol warnx
/usr/lib/libbsd.so.0: ignoring missing symbol sigpending
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_api.so
random: device unblocked.
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_app.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_env.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_file.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_fs.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_hardware.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_network.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_os.so
httpserver: loaded plugin from path: /usr/mgmt/plugins/libhttpserver-api_trace.so
sysconf(): stubbed for parameter 43
/#
"
As you can see I would assign the IP 192.168.1.120 to the 1st OSv instance and 192.168.1.121 to the 2nd one and then pass the opposite as "-a" argument so that cli on each instance could communicate with each other.
Finally, another key thing is to make sure that you use unique MAC addresses for each OSv instance (please note --mac argument). The 1st one uses 52:54:00:12:34:01 and the 2nd 52:54:00:12:34:02 in my case.
Lastly, I will try to update some of the wiki pages especially the one about running OSv on VBox, and maybe add a new one giving more details about the networking setup.
Waldek
BTW I still think it should be possible to run OSv on Virtual Box directly and have those instances communicate to each other if that is what you are interested in. I think there may be some documentation issues we need to overcome.