Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 1 Jul 2004 00:49:10 +0200 (CEST)
From:      Per Hedeland <per@hedeland.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/68532: Add support for multiple VMWare instances
Message-ID:  <200406302249.i5UMnAdW050481@tordmule.bluetail.com>
Resent-Message-ID: <200406302250.i5UMo5Hr003944@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         68532
>Category:       ports
>Synopsis:       Add support for multiple VMWare instances
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 30 22:50:05 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator:     Per Hedeland
>Release:        FreeBSD 5.2.1-RELEASE i386
>Organization:
None
>Environment:
System: FreeBSD tordmule.bluetail.com 5.2.1-RELEASE FreeBSD 5.2.1-RELEASE #2: Fri May 14 17:05:58 CEST 2004 per@tordmule.bluetail.com:/usr/src/sys/i386/compile/TORDMULE i386

Port: vmware3-3.2.1.2242_7,1

>Description:
	It isn't possible to run multiple VMWare instances with the current
	port (at least not with networking) - starting the second one
	fails with:

	Could not open /dev/vmnet1: Device or resource busy
	Failed to configure ethernet0.

	From some experimentation and source browsing, it seems that the
	only problem is that each instance needs its own vmnet interface.
	This is a limitation of course, but I think it's acceptable -
	however the config and start script can't deal with it.

>How-To-Repeat:
	Start a networked VMWare instance. Start one more.

>Fix:
	The patches below extend the per-vmnet config of IP address and
	netmask that is already in /usr/local/etc/vmware/config, making
	also "Bridged" and "BridgeInterface" be per-vmnet parameters,
	and make the start script set up as many vmnet interfaces as
	specified, in the appropriate mode. For bridged mode, a single
	bridge per physical BridgeInterface is created, connecting the
	BridgeInterface and those vmnet interfaces that specify that
	BridgeInterface. Additionally the VMWare config must specify
	"Custom" and "/dev/vmnetN" for the Ethernet Adapter of those
	instances that won't be using vmnet1.

	Also the arguably inappropriate and in some cases problematic
	setting of an IP address on vmnet devices that are in a bridge
	was removed - whether this (and in particular the method used)
	works may be ${OSVERSION}-dependant (it works fine on
	5.2.1-RELEASE), in which case the
	VMNET_ADDR_ON_BRIDGED_INTERFACE setting in the Makefile can be
	appropriately conditionalized.

	Also the on-the-fly creation of vmnet interfaces will surely not
	work in pre-devfs releases - but the "standard" setup/config
	done at port install time is not dependant on that, it is only
	needed when the user actually adds additional vmnet interfaces
	in the config file (via manual editing). The port install setup
	will produce a config that is functionally equivalent to what is
	done without the patches, modulo the
	VMNET_ADDR_ON_BRIDGED_INTERFACE thing.

	With this, I have successfully run 4 networked VMWare instances
	simultaneously, two bridged and two non-bridged, with this
	config file:

vmware.fullpath = "/usr/local/lib/vmware/bin/vmware"
wizard.fullpath = "/usr/local/lib/vmware/bin/vmware-wizard"
dhcpd.fullpath = "/usr/local/lib/vmware/bin/vmnet-dhcpd"
loop.fullpath = "/usr/local/lib/vmware/bin/vmware-loop"
libdir = "/usr/local/lib/vmware"
vmnet1.Bridged = "NO"
vmnet1.BridgeInterface = ""
vmnet1.HostOnlyAddress = "172.31.254.1"
vmnet1.HostOnlyNetMask = "255.255.255.240"
vmnet2.Bridged = "NO"
vmnet2.BridgeInterface = ""
vmnet2.HostOnlyAddress = "172.31.254.17"
vmnet2.HostOnlyNetMask = "255.255.255.240"
vmnet3.Bridged = "YES"
vmnet3.BridgeInterface = "em0"
vmnet3.HostOnlyAddress = "192.168.0.1"
vmnet3.HostOnlyNetMask = "255.255.255.0"
vmnet4.Bridged = "YES"
vmnet4.BridgeInterface = "em0"
vmnet4.HostOnlyAddress = "192.168.0.1"
vmnet4.HostOnlyNetMask = "255.255.255.0"

Resulting network config:

# ifconfig 
em0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
        options=3<RXCSUM,TXCSUM>
        inet 192.168.128.49 netmask 0xffffff00 broadcast 192.168.128.255
        ether 00:0c:f1:de:9e:c0
        media: Ethernet autoselect (100baseTX <full-duplex>)
        status: active
plip0: flags=8810<POINTOPOINT,SIMPLEX,MULTICAST> mtu 1500
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
        inet 127.0.0.1 netmask 0xff000000 
vmnet1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 172.31.254.1 netmask 0xfffffff0 broadcast 172.31.254.15
        ether 00:bd:70:05:00:01
        Opened by PID 949
vmnet2: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 1500
        inet 172.31.254.17 netmask 0xfffffff0 broadcast 172.31.254.31
        ether 00:bd:71:05:00:02
        Opened by PID 2011
vmnet3: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
        ether 00:bd:73:05:00:03
        Opened by PID 950
vmnet4: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
        ether 00:bd:7e:05:00:04
        Opened by PID 2019

# ngctl list
There are 7 total nodes:
  Name: ngctl50429      Type: socket          ID: 00000021   Num hooks: 0
  Name: vmnet_bridge1   Type: bridge          ID: 00000016   Num hooks: 4
  Name: vmnet4          Type: ether           ID: 0000000e   Num hooks: 1
  Name: vmnet3          Type: ether           ID: 00000004   Num hooks: 1
  Name: vmnet2          Type: ether           ID: 00000003   Num hooks: 0
  Name: vmnet1          Type: ether           ID: 00000002   Num hooks: 0
  Name: em0             Type: ether           ID: 00000001   Num hooks: 2

# ngctl show vmnet_bridge1:
  Name: vmnet_bridge1   Type: bridge          ID: 00000016   Num hooks: 4
  Local hook      Peer name       Peer type    Peer ID         Peer hook      
  ----------      ---------       ---------    -------         ---------      
  link3           vmnet4          ether        0000000e        lower          
  link2           vmnet3          ether        00000004        lower          
  link1           em0             ether        00000001        upper          
  link0           em0             ether        00000001        lower          



--- /usr/ports/emulators/vmware3/files/001.vmware.sh.ORIG	Sat Jun 12 01:35:29 2004
+++ /usr/ports/emulators/vmware3/files/001.vmware.sh	Wed Jun 23 01:23:31 2004
@@ -24,10 +24,7 @@
 vmware=`vmware_config vmware.fullpath`
 vmware_libdir=`vmware_config libdir`
 networking=@@NETWORKING@@
-bridged=@@BRIDGED@@
-bridge_interface=@@BRIDGE_INTF@@
-host_ip=`vmware_config vmnet1.HostOnlyAddress`
-netmask=`vmware_config vmnet1.HostOnlyNetMask`
+addr_on_bridge_if=@@ADDR_BRIDGE_IF@@
 dev_vmnet1=/dev/vmnet1
 
 if [ ! -x $vmware ]; then
@@ -54,22 +51,47 @@
 		echo "Your VMware installation seems broken.  Please reinstall VMware port." >&2
 		exit 255
 	fi
-       (echo -n > $dev_vmnet1) 2>/dev/null || \
-	    echo -n > /dev/vmnet1 2>&1
-	ifconfig vmnet1 $host_ip netmask $netmask
-	if [ X$bridged = XYES ]; then
-	    kldstat -v | grep netgraph >/dev/null || kldload netgraph.ko
-	    kldstat -v | grep ng_ether >/dev/null || kldload ng_ether.ko
-	    kldstat -v | grep ng_bridge >/dev/null || kldload ng_bridge.ko
-	    ngctl mkpeer vmnet1: bridge lower link0
-	    ngctl name vmnet1:lower vmnet_bridge
-	    ngctl connect vmnet_bridge: ${bridge_interface}: link1 lower
-	    ngctl connect vmnet_bridge: ${bridge_interface}: link2 upper
-	    ngctl msg ${bridge_interface}: setautosrc 0
-	    ngctl msg ${bridge_interface}: setpromisc 1
-	    ngctl msg vmnet1: setautosrc 0
-	    ngctl msg vmnet1: setpromisc 1
-	fi
+	vmnet_no=1
+	bridge_no=1
+	while true; do
+	    vmnet=vmnet$vmnet_no
+	    vmnet_no=`expr $vmnet_no + 1`
+	    bridged=`vmware_config $vmnet.Bridged`
+	    if [ X$bridged = X ]; then
+		break
+	    fi
+	    host_ip=`vmware_config $vmnet.HostOnlyAddress`
+	    netmask=`vmware_config $vmnet.HostOnlyNetMask`
+	    echo -n > /dev/$vmnet 2>&1
+	    ifconfig $vmnet $host_ip netmask $netmask
+	    if [ X$bridged = XYES ]; then
+		if [ X$addr_on_bridge_if = XNO ]; then
+		    # XXX Still need to configure + delete to make it RUNNING
+		    ifconfig $vmnet delete $host_ip
+		fi
+		bridge_interface=`vmware_config $vmnet.BridgeInterface`
+		eval vmnet_bridge=\$vmnet_bridge_$bridge_interface
+		if [ X$vmnet_bridge = X ]; then
+		    kldstat -v | grep netgraph >/dev/null || kldload netgraph.ko
+		    kldstat -v | grep ng_ether >/dev/null || kldload ng_ether.ko
+		    kldstat -v | grep ng_bridge >/dev/null || kldload ng_bridge.ko
+		    vmnet_bridge=vmnet_bridge$bridge_no
+		    bridge_no=`expr $bridge_no + 1`
+		    eval vmnet_bridge_$bridge_interface=$vmnet_bridge
+		    ngctl mkpeer ${bridge_interface}: bridge lower link0
+		    ngctl name ${bridge_interface}:lower ${vmnet_bridge}
+		    ngctl connect ${vmnet_bridge}: ${bridge_interface}: link1 upper
+		    ngctl msg ${bridge_interface}: setautosrc 0
+		    ngctl msg ${bridge_interface}: setpromisc 1
+		    eval ${vmnet_bridge}_linkno=2
+		fi
+		eval linkno=\$${vmnet_bridge}_linkno
+		eval ${vmnet_bridge}_linkno=`expr $linkno + 1`
+		ngctl connect ${vmnet_bridge}: ${vmnet}: link$linkno lower
+		ngctl msg ${vmnet}: setautosrc 0
+		ngctl msg ${vmnet}: setpromisc 1
+	    fi
+	done
     fi
     echo -n " VMware" >&2
     ;;
@@ -77,13 +99,35 @@
 stop)
     kldunload vmmon_${suffix}
     if [ $networking -eq 1 ]; then
-	ifconfig vmnet1 down
-	ifconfig vmnet1 delete $host_ip
-	if [ X$bridged = XYES ]; then
-	    ngctl shutdown vmnet_bridge:
-	    ngctl msg ${bridge_interface}: setautosrc 1
-	    ngctl msg ${bridge_interface}: setpromisc 0
-	fi
+	vmnet_no=1
+	bridge_no=1
+	while true; do
+	    vmnet=vmnet$vmnet_no
+	    vmnet_no=`expr $vmnet_no + 1`
+	    bridged=`vmware_config $vmnet.Bridged`
+	    if [ X$bridged = X ]; then
+		break
+	    fi
+	    host_ip=`vmware_config $vmnet.HostOnlyAddress`
+	    ifconfig $vmnet down
+	    if [ X$bridged = XYES ]; then
+		if [ X$addr_on_bridge_if = XYES ]; then
+		    ifconfig $vmnet delete $host_ip
+		fi
+		bridge_interface=`vmware_config $vmnet.BridgeInterface`
+		eval vmnet_bridge=\$vmnet_bridge_$bridge_interface
+		if [ X$vmnet_bridge = X ]; then
+		    vmnet_bridge=vmnet_bridge$bridge_no
+		    bridge_no=`expr $bridge_no + 1`
+		    eval vmnet_bridge_$bridge_interface=$vmnet_bridge
+		    ngctl msg ${bridge_interface}: setautosrc 1
+		    ngctl msg ${bridge_interface}: setpromisc 0
+		    ngctl shutdown ${vmnet_bridge}:
+		fi
+	    else
+		ifconfig $vmnet delete $host_ip
+	    fi
+	done
 	kldunload vmnet.ko
     fi
     ;;
--- /usr/ports/emulators/vmware3/files/config.ORIG	Tue Oct 21 19:36:03 2003
+++ /usr/ports/emulators/vmware3/files/config	Tue Jun 22 00:26:55 2004
@@ -3,5 +3,7 @@
 dhcpd.fullpath = "@@PREFIX@@/lib/vmware/bin/vmnet-dhcpd"
 loop.fullpath = "@@PREFIX@@/lib/vmware/bin/vmware-loop"
 libdir = "@@PREFIX@@/lib/vmware"
+vmnet1.Bridged = "@@BRIDGED@@"
+vmnet1.BridgeInterface = "@@BRIDGE_INTF@@"
 vmnet1.HostOnlyAddress = "@@HOST_IP@@"
 vmnet1.HostOnlyNetMask = "@@NETMASK@@"
--- /usr/ports/emulators/vmware3/Makefile.ORIG	Sun Jun 13 00:02:41 2004
+++ /usr/ports/emulators/vmware3/Makefile	Wed Jun 23 00:58:38 2004
@@ -68,6 +68,8 @@
 VMNET1_MINOR=	0x00800001
 .endif
 
+VMNET_ADDR_ON_BRIDGED_INTERFACE= NO
+
 SCRIPTS_ENV+=	LINUXBASE="${LINUXBASE}" \
 		VMNET_HOST_IP="${VMNET_HOST_IP}" \
 		VMNET_NETMASK="${VMNET_NETMASK}" \
@@ -134,6 +136,8 @@
 
 setoptions:
 	${SED} 	-e 's;@@PREFIX@@;${PREFIX};' \
+		-e 's;@@BRIDGED@@;${VMNET_BRIDGED};' \
+		-e 's;@@BRIDGE_INTF@@;${VMNET_BRIDGED_INTERFACE};' \
 		-e 's;@@HOST_IP@@;${VMNET_HOST_IP};' \
 		-e 's;@@NETMASK@@;${VMNET_NETMASK};' \
 		${FILESDIR}/config > ${WRKDIR}/config
@@ -141,8 +145,7 @@
 	${SED} 	-e 's;@@PREFIX@@;${PREFIX};' \
 		-e 's;@@LINUXBASE@@;${LINUXBASE};' \
 		-e 's;@@NETWORKING@@;${VMNET_NETWORKING};' \
-		-e 's;@@BRIDGED@@;${VMNET_BRIDGED};' \
-		-e 's;@@BRIDGE_INTF@@;${VMNET_BRIDGED_INTERFACE};' \
+		-e 's;@@ADDR_BRIDGE_IF@@;${VMNET_ADDR_ON_BRIDGED_INTERFACE};' \
 		${FILESDIR}/001.vmware.sh > ${WRKDIR}/001.vmware.sh
 
 	${SED} 	-e 's;@@PREFIX@@;${PREFIX};' \
>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200406302249.i5UMnAdW050481>