Recently there was an issue with particular dedicated hosts having network issues due to high traffic triggering a known bug in particular RealTek NICs.

Unfortunately puppet doesn’t expose facts about the networking equipment of a server so I wrote the below to expose the NIC drivers in use, their firmware version and which interfaces use them. Based on this, we can limit the provisioning of frequent high-traffic nodes on those dedicated servers.

# Facter already knows about interfaces
drivers = Hash.new
drivers_list = Array.new
driver_versions = Hash.new
Facter.value(:interfaces).split(',').each do |int|
  # call ethtool to get the driver for this NIC
  driver = %x{/sbin/ethtool -i #{int} 2>/dev/null | grep 'driver: '}.chomp.sub("driver: ", "")
  version = %x{/sbin/ethtool -i #{int} 2>/dev/null | grep 'version: '}.chomp.sub("version: ", "")
  if driver == ''
    driver = 'virtual'
  end

  if not drivers.has_key?(driver)
    drivers[driver] = Array.new
  end

  drivers[driver] << int
  driver_versions[driver] = version
  drivers_list << driver
end

# Add fact that is a list of all drivers
Facter.add("nic_drivers") do
  setcode do
    drivers_list.join(',')
  end
end

# Add Fact per driver, with comma separated interfaces in each Fact
driver_versions.each do |driver,version|
  Facter.add("nic_driver_#{driver}_version") do
    confine :kernel => :linux
    setcode do
      version
    end
  end
end

# Fact that creates Facter facts of the format nic_driver_
# that contain a comma separated string of all the networking interfaces that
# use this driver.
# Example:
#  nic_driver_bnx2 => em1,em2
#  nic_driver_bonding => bond0,bond16
#  nic_driver_igb => p2p1,p2p2,p2p3,p2p4
#  nic_driver_virtual => lo

# Add Fact per driver, with comma separated interfaces in each Fact
drivers.each do |driver,ints|
  Facter.add("nic_driver_#{driver}") do
    confine :kernel => :linux
    setcode do
      ints.join(',')
    end
  end
end

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.