There was another interesting thread today on the VMTN community forums about disabling an unused vmnic from an ESXi host due to false alarms being generated from HP SIM. Due to the specific hardware version, disabling the vmnic through the BIOS was not an option and there were no alternatives from the discussion.
I decided to dig a bit to see what I could find and stumbled upon a neat little utility called vmkchdev (VMkernel Change Device?) and from what I can tell provides a method passing a particular device to be controlled by either the VMkernel or as a passthrough device to a virtual machine (think VMDirect Path).
Disclaimer: Please note, this is using an undocumented utility. You should test this out in a development/lab environment before using and you may want to also contact VMware support to get their blessings***
~ # vmkchdev
Usage:
-s (scan device)
-v (give device to vmkernel)
-p (give device to passthru/VM)
-l (list device state)
-L (list device state with details)
[0x][seg:[bus[:slot[.func]]]]
What I found while testing the utility is by passing it over as a passthrough device, the vmnic is actually unrepresented to the VMkernel and does not show up under network adapters or even the unused/unlinked adapter list in the vSwitch configurations. It seems that it is just masks the device away from the VMkernel as you can still see the active configuration in esx.conf and you can see the device listed using vmkchdev.
Here is an example of an unused physical nic vmnic1 that we would like to disable and unpresent to an ESXi host.
Here is the output from esxcfg-nics:
First we need to identify the vmnic's PCI slot, we do by running the "-l" or list operation and searching for the particular vmnice device.
~ # vmkchdev -l | grep vmnic1
000:002:01.0 8086:100f 15ad:0750 vmkernel vmnic1
Next we will pass the device from the VMkernel to passthrough/VM using the "-p" flag and specifying the PCI slot, which in this case it is 000:002:01.0. We will also need to refresh the network section so the changes are reflected in the vSphere Client by using vim-cmd.
~ # vmkchdev -p 000:002:01.0
~ # vim-cmd hostsvc/net/refresh
If we list our vmnic again using vmkchdev, you will notice the device is now owned by passthru versus the VMkernel.
~ # vmkchdev -l | grep vmnic1
000:002:01.0 8086:100f 15ad:0750 passthru vmnic1
Now if we check the output of esxcfg-nics and the vSphere Client, you will notice that vmnic1 is no where to be found
If you would like to enable or re-present the disabled vmnic, you just need to pass the device back over to VMkernel by using the "-v" flag.
~ # vmkchdev -v 000:002:01.0
~ # vim-cmd hostsvc/net/refresh
Your vmnic should now re-appear on all your screens and any existing NIC teams that may have exists is automatically restored. This trick actually works on both a used and unused vmnic
If you are trying to do this on ESX, vmkchdev actually has an additional option called "console" for the Service Console.
[root@esx41-1 ~]# vmkchdev
Usage:
-s (scan device)
-c (give device to console)
-v (give device to vmkernel)
-p (give device to passthru/VM)
-l (list device state)
-L (list device state with details)
[0x][seg:[bus[:slot[.func]]]]
I found that you need to pass the vmnic from VMkernel to Console, passing it to passthru/VM will not work and an error is thrown if you do. Again, you can easily re-enable by passing it back to the VMkernel
vmkchdev -c 000:002:01.0
If you would like to automatically persist this change across reboots, specifically for ESXi as changes are not saved. You will need to add the following lines to /etc/rc.local which will execute the disabling of the vmnic's after bootup.
/sbin/vmkchdev -p 000:002:01.0
vim-cmd hostsvc/net/refresh
You will also need to run /sbin/auto-backup.sh to ensure the changes to /etc/rc.local are saved and reloaded upon the next reboot. For ESX, you can place it in /etc/rc.local without having to do anything extra as the changes persists across reboots for classic ESX
Now you can play hide and seek with your vmnic's without resorting to a system reboot or touching the BIOS. Though ideally, if you do have unused devices, you should definitely disable them in the BIOS if you have the option. On a side note, this might be a fun trick to play on one of your co-workers by hiding all vmnics 😉
esxinewbie says
Hello,
I tried this myself on ESXi and it seems to work only for integrated vmnic? Or at least I was not able to successfully issue the command for others vmnic. The result was the following error:
vmkchdev failed with 0xbad0004
Furthermore issuing the command with –p even for an integrated vmnic caused the SSH session to hang, and had to terminate it.
Then no way to use –v: same error.
Any suggestions?
Thanks in advance.
William says
@esxinewbie
Interesting, I was able to get this to work on non-embedded NICs. Perhaps it's hardware specific, I don't have any other solution as this interface is not supported and YMMV. The only other option is to disable the NICS in your BIOS if you can
esxinewbie says
In the meantime I was able to try the suggestions by Andreas Peetz, as well, about hiding unused FlexNICs.
I have a HP DL370 with 4 embedded NICS and several additional dual port network adapters (1Gb and 10Gb) for redundancy purposes.
It happen that on some of them just 1 port is used and it seems as well that using Andreas method is not possible to just disable 1 port, but the whole dual channel network card only. This could eventually explain the failure message had using your method?
This behavior is of course of no use in my case. And the BIOS just offers to disable the whole network card, as well, not just 1 port…
Any ideas?
randyvmware says
I've recommend this method (moving devices to passthru) to prevent HP utilities from complaining about devices to customers before as well.
But it isn't necessary to call vmkchdev directly, just go to Hardware->Advanced Configuration in the host settings and select a device that way. It is a lot safer, and automatically persists.
P.S. It was a pain to post this as I had to create a bogus blog to do so. You should just allow people to make comments directly.
Pozinux says
Hi !
Thanks for this post. I used it to hide SATA controller for a customer.
The only difference is in this command :
vim-cmd hostsvc/net/refresh
Replace "net" by "storage"
Thanks again ! Works great !
shashank attapally says
Current situation vmnic is down showing up but logically it was not working.
Used command
esxcli network nic down -n vmnicX – This worked.
esxcli network nic up -n vmnicX- this did not work
so blogged this page and found vmkchdev..
~ # vmkchdev -l | grep vmnic9
000:005:00.5 19a2:0700 103c:3314 vmkernel vmnic9
~ # vmkchdev -s 000:005:00.5
~ # vmkchdev -c 000:005:00.5
Usage: -s (scan device)
-v (give device to vmkernel)
-p (give device to passthru/VM)
-l (list device state)
-L (list device state with details)
[0x][seg:[bus[:slot[.func]]]]
~ # vmkchdev -p 000:005:00.5
~ # vmkchdev -v 000:005:00.5
Now vmnic 9 is up and functional.
Thanks guys,
Shashank Gattapally
Cyno says
This took me a while to figure out, so I thought I'd share, despite the age of this commentary:
$esxcli = Get-EsxCli -VMHost $VMHost -V2 -Server $vCenter
$esxcli.network.nic.down.Invoke(@{"nicname"="vmnicX"})
$esxcli.network.nic.List.Invoke().Where({$_.Name -eq "vmnicX"})
#OR
$esxcli.network.nic.List.Invoke() | Sort Name | Select Name,AdminStatus,Link*,Speed,PCIDevice | FT -A
This sets the AdminStatus to Down