Source code for xcp.net.biosdevname

# Copyright (c) 2013, Citrix Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""
Utility functions to get information from biosdevname about the
current network state.
"""

__version__ = "1.0.0"
__author__ = "Andrew Cooper"

from subprocess import Popen, PIPE

__ALL_POLICIES = [ "physical", "all_ethN" ]

def __run_all_devices(policy = "physical"):
    """
    Run 'biosdevname -d' for a specified policy.
    Return (stdout, stderr, returncode) tuple.
    """

    proc = Popen(["/sbin/biosdevname", "--policy", policy,
                  "-d", "-x"], stdout=PIPE, stderr=PIPE, universal_newlines=True)

    stdout, stderr = proc.communicate()

    return ( stdout, stderr, proc.returncode )

[docs] def all_devices_all_names(): """ Get all information, including all names, for all devices. Returns a dictionary of devices, indexed by current kernel name. All entries will be string to string mappings, with the exception of 'BIOS device' which will be a dictonary of policies to names. """ devices = {} for policy in __ALL_POLICIES: (stdout, _, retcode) = __run_all_devices(policy) if retcode: continue for device in (x.strip() for x in stdout.split("\n\n") if len(x)): dinfo = {} for l in device.split("\n"): k, v = l.split(":", 1) dinfo[k.strip()] = v.strip() if ( "Kernel name" not in dinfo or "BIOS device" not in dinfo ): continue # Treat USB devices the PCI device of their host adapter if dinfo.get("Bus Info", "").startswith("usb-") and "eth" in dinfo["Kernel name"]: dinfo["Bus Info"] = dinfo["Bus Info"].split('-')[1] kname = dinfo["Kernel name"] if kname in devices: devices[kname]["BIOS device"][policy] = dinfo["BIOS device"] else: devices[kname] = dinfo devices[kname]["BIOS device"] = {policy: dinfo["BIOS device"]} return devices
[docs] def has_ppn_quirks(bdn_dicts): # CA-75599 - Assert that no devices share the same SMBIOS Instance. Some # BIOSes have multiple different nics with the same value set, which causes # biosdevname to mis-name its physical policy names (emXX, pciXpX etc) smbios_instances = set() for info in bdn_dicts: instance = info.get("SMBIOS Instance", None) if instance: if instance in smbios_instances: return True else: smbios_instances.add(instance) return False