[libvirt] [libvirt-test-API][PATCH] npiv: Add basic NPIV test case

Alex Jia ajia at redhat.com
Tue Oct 22 10:18:12 UTC 2013


On 10/22/2013 12:28 PM, jmiao wrote:
> The original NPIV test function create_virtual_hba doesn't check the
> validation of fabric_wwn, this patch modify create_virtual_hba to check
> fabric_wwn whether is invalid (0xffffffff).

Is it always right for different vendor's HBAs? IMHO, you may check 'port_state' of the fc_host, as usual,
it may be 'Online'/'Linkup' or 'Offline'/'Linkdown', if the state is former, and then you can create a vHBA,
otherwise, you will hit error like "error: Write of 'XXXX:XXXX' to '/sys/class/fc_host/host$NUM/vport_create'
during vport create/delete failed: Operation not supported".

e.g.

# cat /tmp/check_vhba.sh
for i in $(virsh nodedev-list --cap scsi_host); do
   if virsh nodedev-dumpxml $i | grep vport_ops>  /dev/null; then
     echo $i;
   fi
done

# sh /tmp/check_vhba.sh
scsi_host4
scsi_host5

# ls /sys/class/fc_host/
host4  host5

# cat /sys/class/fc_host/host4/port_state
Linkdown

# cat /sys/class/fc_host/host5/port_state
Online

# cat /tmp/vhba.scsi_host4.xml

     <device>

       <parent>scsi_host4</parent>

       <capability type='scsi_host'>

         <capability type='fc_host'>

         </capability>

       </capability>

     </device>

# virsh nodedev-create /tmp/vhba.scsi_host4.xml
error: Failed to create node device from /tmp/vhba.scsi_host4.xml
error: Write of '5001a4aeea4b54c9:5001a4a9c0f07593' to '/sys/class/fc_host/host4/vport_create' during vport create/delete failed: Operation not supported


# cat /tmp/vhba.scsi_host5.xml

     <device>

       <parent>scsi_host5</parent>

       <capability type='scsi_host'>

         <capability type='fc_host'>

         </capability>

       </capability>

     </device>

# virsh nodedev-create /tmp/vhba.scsi_host5.xml
Node device scsi_host6 created from /tmp/vhba.scsi_host5.xml


Alex


> One the other hand, add a function destroy_virtual_hba to clean the vHBA which
> is created by create_virtual_hba.
>
> Add a global variable wwnn to global.cfg for create_virtual_hba. And add the
> test case conf file basic_npiv.conf.
>
> Signed-off-by: jmiao<jmiao at redhat.com>
> ---
>   cases/basic_npiv.conf             |  3 +++
>   global.cfg                        | 10 ++++++++-
>   repos/npiv/create_virtual_hba.py  | 24 +++++++++++---------
>   repos/npiv/destroy_virtual_hba.py | 46 +++++++++++++++++++++++++++++++++++++++
>   4 files changed, 72 insertions(+), 11 deletions(-)
>   create mode 100644 cases/basic_npiv.conf
>   create mode 100644 repos/npiv/destroy_virtual_hba.py
>
> diff --git a/cases/basic_npiv.conf b/cases/basic_npiv.conf
> new file mode 100644
> index 0000000..b9cbd04
> --- /dev/null
> +++ b/cases/basic_npiv.conf
> @@ -0,0 +1,3 @@
> +npiv:create_virtual_hba
> +
> +npiv:destroy_virtual_hba
> diff --git a/global.cfg b/global.cfg
> index db8f71e..a35b985 100644
> --- a/global.cfg
> +++ b/global.cfg
> @@ -210,7 +210,15 @@ testnic = eth1
>
>   # a PCI device to use for attach/detach/reset tests
>   # for example testpci = 00:19.0
> -testpci =
> +testpci = 00:19.0
> +
> +################################################################
> +#
> +# NPIV wwpn
> +#
> +
> +# a word wide port name to use for create_virtual_hba tests
> +wwnn =
>
>   ################################################################
>   #
> diff --git a/repos/npiv/create_virtual_hba.py b/repos/npiv/create_virtual_hba.py
> index 0a02a9b..b637127 100644
> --- a/repos/npiv/create_virtual_hba.py
> +++ b/repos/npiv/create_virtual_hba.py
> @@ -21,7 +21,7 @@ def check_nodedev_create(wwpn, device_name):
>          vport name in all FC list, to see if it exists.
>       """
>
> -    pname_list = commands.getoutput("ls -1 -d /sys/class/*_host/host*/* \
> +    pname_list = commands.getoutput("ls -1 -d /sys/class/*_host/host*/*
>                                        | grep port_name")
>       for pname in pname_list.split("\n"):
>           portid = open(pname).read()[2:].strip('\n')
> @@ -38,11 +38,11 @@ def check_nodedev_parent(nodedev_obj, device_parent, device_name):
>
>       current_parent = nodedev_obj.parent()
>       if device_parent == current_parent:
> -        logger.info("The parent of node device '%s' is %s" \
> +        logger.info("The parent of node device '%s' is %s"
>                       % (device_name, current_parent))
>           return True
>       else:
> -        logger.info("Refer to bug 593995. The parent of node device \
> +        logger.info("Refer to bug 593995. The parent of node device
>                       '%s' is '%s'" % (device_name, current_parent))
>           return False
>
> @@ -63,35 +63,39 @@ def create_virtual_hba(params):
>           fc_xml = nodedev.XMLDesc(0)
>           fc_cap = re.search('vport_ops', fc_xml)
>           if fc_cap:
> +            doc = xml.dom.minidom.parseString(fc_xml)
> +            logger.info("NPIV support on '%s'" % fc_name)
> +            fabric_wwn = doc.getElementsByTagName('fabric_wwn')[0].childNodes[0].nodeValue.encode('ascii', 'ignore')
> +            if fabric_wwn == 'ffffffff':
> +                logger.info("fabric_wwn of '%s' is ffffffff" % fc_name)
> +                continue
>               device_parent = fc_name
>               xmlstr = xmlstr.replace('PARENT', device_parent)
> -            doc = xml.dom.minidom.parseString(fc_xml)
>               wwnn_node = doc.getElementsByTagName('wwnn')[0]
>               xmlstr = xmlstr.replace('WWNN', wwnn_node.childNodes[0].nodeValue.encode('ascii', 'ignore'))
> -            logger.info("NPIV support on '%s'" % fc_name)
>               break
>           else:
>               logger.info("No NPIV capabilities on '%s'" % fc_name)
>
>       logger.debug("node device xml:\n%s" % xmlstr)
> -    return 0
>
>       try:
>           logger.info("creating a virtual HBA ...")
>           nodedev_obj = conn.nodeDeviceCreateXML(xmlstr, 0)
>           dev_name = nodedev_obj.name()
>
> -        if check_nodedev_create(wwpn, dev_name) and \
> +        if check_nodedev_create(wwpn, dev_name) and
>               check_nodedev_parent(nodedev_obj, device_parent, dev_name):
> -            logger.info("the virtual HBA '%s' was created successfully" \
> +            logger.info("the virtual HBA '%s' was created successfully"
>                           % dev_name)
> +            sharedmod.data['vhba'] = dev_name
>               return 0
>           else:
> -            logger.error("fail to create the virtual HBA '%s'" \
> +            logger.error("fail to create the virtual HBA '%s'"
>                            % dev_name)
>               return 1
>       except libvirtError, e:
> -        logger.error("API error message: %s, error code is %s" \
> +        logger.error("API error message: %s, error code is %s"
>                        % (e.message, e.get_error_code()))
>           logger.error("Error: fail to create %s virtual hba" % dev_name)
>           return 1
> diff --git a/repos/npiv/destroy_virtual_hba.py b/repos/npiv/destroy_virtual_hba.py
> new file mode 100644
> index 0000000..7864ed4
> --- /dev/null
> +++ b/repos/npiv/destroy_virtual_hba.py
> @@ -0,0 +1,46 @@
> +#!/usr/bin/env python
> +# To test vHBA destroying.
> +
> +import libvirt
> +from libvirt import libvirtError
> +
> +from src import sharedmod
> +
> +required_params = ()
> +optional_params = {}
> +
> +def destroy_virtual_hba(params):
> +    """Destroy the vHBA created before."""
> +    global logger
> +    logger = params['logger']
> +
> +    conn = sharedmod.libvirtobj['conn']
> +
> +    if not sharedmod.data.has_key('vhba'):
> +        logger.error("Failed to find the created vhba.")
> +        return 1
> +
> +    dev_name = sharedmod.data['vhba']
> +
> +    logger.info("destroying the virtual HBA %s" % dev_name)
> +
> +
> +    try:
> +        nodedev_obj = conn.nodeDeviceLookupByName(dev_name)
> +
> +        nodedev_obj.destroy()
> +
> +        scsi_list = conn.listDevices('scsi_host', 0)
> +
> +        for fc_name in scsi_list:
> +            if fc_name == dev_name:
> +                logger.error("Fail to destroy the virtual HBA %s" % dev_name)
> +                return 1
> +
> +    except libvirtError, e:
> +        logger.error("API error message: %s, error code is %s"
> +                     % (e.message, e.get_error_code()))
> +        logger.error("Error: fail to destroy %s virtual hba" % dev_name)
> +        return 1
> +
> +    return 0




More information about the libvir-list mailing list