2014-03-06 12:08:36 +04:00
/*
* Copyright ( C ) 2014 SUSE LINUX Products GmbH , Nuernberg , Germany .
2016-04-06 16:46:49 +03:00
* Copyright ( C ) 2014 - 2016 Red Hat , Inc .
2014-03-06 12:08:36 +04:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library . If not , see
* < http : //www.gnu.org/licenses/>.
*
* Author : Chunyan Liu < cyliu @ suse . com >
*/
# include <config.h>
# include "testutils.h"
# ifdef __linux__
# include <stdlib.h>
# include <stdio.h>
# include <sys / types.h>
# include <sys / stat.h>
# include <sys / ioctl.h>
# include <fcntl.h>
# include "virlog.h"
# include "virhostdev.h"
# define VIR_FROM_THIS VIR_FROM_NONE
2014-02-28 16:16:17 +04:00
VIR_LOG_INIT ( " tests.hostdevtest " ) ;
2017-11-03 15:09:47 +03:00
# define CHECK_LIST_COUNT(list, cnt) \
do { \
size_t actualCount ; \
if ( ( actualCount = virPCIDeviceListCount ( list ) ) ! = cnt ) { \
virReportError ( VIR_ERR_INTERNAL_ERROR , \
" Unexpected count of items in " # list " : %zu, " \
" expecting %zu " , actualCount , ( size_t ) cnt ) ; \
goto cleanup ; \
} \
2016-03-02 17:23:51 +03:00
} while ( 0 )
2014-03-06 12:08:36 +04:00
# define TEST_STATE_DIR abs_builddir " / hostdevmgr"
static const char * drv_name = " test_driver " ;
static const char * dom_name = " test_domain " ;
static const unsigned char * uuid =
( unsigned char * ) ( " f92360b0-2541-8791-fb32-d1f838811541 " ) ;
static int nhostdevs = 3 ;
static virDomainHostdevDefPtr hostdevs [ ] = { NULL , NULL , NULL } ;
static virPCIDevicePtr dev [ ] = { NULL , NULL , NULL } ;
2014-10-28 21:38:04 +03:00
static virHostdevManagerPtr mgr ;
2014-03-06 12:08:36 +04:00
static void
myCleanup ( void )
{
size_t i ;
for ( i = 0 ; i < nhostdevs ; i + + ) {
virPCIDeviceFree ( dev [ i ] ) ;
virDomainHostdevDefFree ( hostdevs [ i ] ) ;
}
if ( mgr ) {
2015-09-15 23:33:36 +03:00
if ( ! getenv ( " LIBVIRT_SKIP_CLEANUP " ) )
2014-04-28 17:34:52 +04:00
virFileDeleteTree ( mgr - > stateDir ) ;
2014-03-06 12:08:36 +04:00
virObjectUnref ( mgr - > activePCIHostdevs ) ;
virObjectUnref ( mgr - > activeUSBHostdevs ) ;
2017-08-10 10:14:36 +03:00
virObjectUnref ( mgr - > inactivePCIHostdevs ) ;
virObjectUnref ( mgr - > activeSCSIHostdevs ) ;
2014-03-06 12:08:36 +04:00
VIR_FREE ( mgr - > stateDir ) ;
VIR_FREE ( mgr ) ;
}
}
static int
myInit ( void )
{
size_t i ;
for ( i = 0 ; i < nhostdevs ; i + + ) {
virDomainHostdevSubsys subsys ;
2017-09-23 14:03:50 +03:00
hostdevs [ i ] = virDomainHostdevDefNew ( ) ;
2014-03-06 12:08:36 +04:00
if ( ! hostdevs [ i ] )
goto cleanup ;
hostdevs [ i ] - > mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ;
subsys . type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI ;
subsys . u . pci . addr . domain = 0 ;
subsys . u . pci . addr . bus = 0 ;
subsys . u . pci . addr . slot = i + 1 ;
subsys . u . pci . addr . function = 0 ;
subsys . u . pci . backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM ;
hostdevs [ i ] - > source . subsys = subsys ;
}
for ( i = 0 ; i < nhostdevs ; i + + ) {
2015-10-23 12:54:07 +03:00
if ( ! ( dev [ i ] = virPCIDeviceNew ( 0 , 0 , i + 1 , 0 ) ) )
2014-03-06 12:08:36 +04:00
goto cleanup ;
2015-10-23 12:54:07 +03:00
virPCIDeviceSetStubDriver ( dev [ i ] , VIR_PCI_STUB_DRIVER_KVM ) ;
2014-03-06 12:08:36 +04:00
}
if ( VIR_ALLOC ( mgr ) < 0 )
goto cleanup ;
if ( ( mgr - > activePCIHostdevs = virPCIDeviceListNew ( ) ) = = NULL )
goto cleanup ;
if ( ( mgr - > activeUSBHostdevs = virUSBDeviceListNew ( ) ) = = NULL )
goto cleanup ;
if ( ( mgr - > inactivePCIHostdevs = virPCIDeviceListNew ( ) ) = = NULL )
goto cleanup ;
if ( ( mgr - > activeSCSIHostdevs = virSCSIDeviceListNew ( ) ) = = NULL )
goto cleanup ;
if ( VIR_STRDUP ( mgr - > stateDir , TEST_STATE_DIR ) < 0 )
goto cleanup ;
if ( virFileMakePath ( mgr - > stateDir ) < 0 )
goto cleanup ;
return 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
myCleanup ( ) ;
return - 1 ;
}
# if HAVE_LINUX_KVM_H
# include <linux / kvm.h>
static bool
virHostdevHostSupportsPassthroughKVM ( void )
{
int kvmfd = - 1 ;
bool ret = false ;
if ( ( kvmfd = open ( " /dev/kvm " , O_RDONLY ) ) < 0 )
goto cleanup ;
# ifdef KVM_CAP_IOMMU
if ( ( ioctl ( kvmfd , KVM_CHECK_EXTENSION , KVM_CAP_IOMMU ) ) < = 0 )
goto cleanup ;
ret = true ;
# endif
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
VIR_FORCE_CLOSE ( kvmfd ) ;
return ret ;
}
# else
static bool
virHostdevHostSupportsPassthroughKVM ( void )
{
return false ;
}
# endif
static int
2016-03-03 18:13:04 +03:00
testVirHostdevPreparePCIHostdevs_unmanaged ( void )
2014-03-06 12:08:36 +04:00
{
int ret = - 1 ;
2016-03-02 17:27:06 +03:00
size_t active_count , inactive_count , i ;
2014-03-06 12:08:36 +04:00
for ( i = 0 ; i < nhostdevs ; i + + )
hostdevs [ i ] - > managed = false ;
2016-03-02 17:15:07 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2014-03-06 12:08:36 +04:00
/* Test normal functionality */
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test 0 hostdevs " ) ;
2014-03-06 12:08:36 +04:00
if ( virHostdevPreparePCIDevices ( mgr , drv_name , dom_name , uuid ,
NULL , 0 , 0 ) < 0 )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
/* Test unmanaged hostdevs */
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test >=1 unmanaged hostdevs " ) ;
2014-03-06 12:08:36 +04:00
if ( virHostdevPreparePCIDevices ( mgr , drv_name , dom_name , uuid ,
hostdevs , nhostdevs , 0 ) < 0 )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count + nhostdevs ) ;
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count - nhostdevs ) ;
2014-03-06 12:08:36 +04:00
/* Test conflict */
2016-03-02 17:15:07 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test: prepare same hostdevs for same driver/domain again " ) ;
2014-03-06 12:08:36 +04:00
if ( ! virHostdevPreparePCIDevices ( mgr , drv_name , dom_name , uuid ,
& hostdevs [ 0 ] , 1 , 0 ) )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test: prepare same hostdevs for same driver, diff domain again " ) ;
2014-03-06 12:08:36 +04:00
if ( ! virHostdevPreparePCIDevices ( mgr , drv_name , " test_domain1 " , uuid ,
& hostdevs [ 1 ] , 1 , 0 ) )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test: prepare same hostdevs for diff driver/domain again " ) ;
2014-03-06 12:08:36 +04:00
if ( ! virHostdevPreparePCIDevices ( mgr , " test_driver1 " , dom_name , uuid ,
& hostdevs [ 2 ] , 1 , 0 ) )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
return ret ;
}
static int
2016-03-03 18:13:04 +03:00
testVirHostdevReAttachPCIHostdevs_unmanaged ( void )
2014-03-06 12:08:36 +04:00
{
int ret = - 1 ;
2016-03-02 17:27:06 +03:00
size_t active_count , inactive_count , i ;
2014-03-06 12:08:36 +04:00
for ( i = 0 ; i < nhostdevs ; i + + ) {
if ( hostdevs [ i ] - > managed ! = false ) {
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " invalid test " ) ;
2014-03-06 12:08:36 +04:00
return - 1 ;
}
}
2016-03-02 17:15:07 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test 0 hostdevs " ) ;
2014-03-06 12:08:36 +04:00
virHostdevReAttachPCIDevices ( mgr , drv_name , dom_name , NULL , 0 , NULL ) ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test >=1 unmanaged hostdevs " ) ;
2014-03-06 12:08:36 +04:00
virHostdevReAttachPCIDevices ( mgr , drv_name , dom_name ,
hostdevs , nhostdevs , NULL ) ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count - nhostdevs ) ;
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count + nhostdevs ) ;
2014-03-06 12:08:36 +04:00
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
return ret ;
}
static int
2016-03-18 20:03:53 +03:00
testVirHostdevPreparePCIHostdevs_managed ( bool mixed )
2014-03-06 12:08:36 +04:00
{
int ret = - 1 ;
2016-03-02 17:33:18 +03:00
size_t active_count , inactive_count , i ;
2014-03-06 12:08:36 +04:00
for ( i = 0 ; i < nhostdevs ; i + + )
hostdevs [ i ] - > managed = true ;
2016-03-02 17:15:07 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
2016-03-02 17:33:18 +03:00
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2014-03-06 12:08:36 +04:00
/* Test normal functionality */
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test >=1 hostdevs " ) ;
2014-03-06 12:08:36 +04:00
if ( virHostdevPreparePCIDevices ( mgr , drv_name , dom_name , uuid ,
hostdevs , nhostdevs , 0 ) < 0 )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count + nhostdevs ) ;
2016-03-18 20:03:53 +03:00
/* If testing a mixed roundtrip, devices are already in the inactive list
* before we start and are removed from it as soon as we attach them to
* the guest */
if ( mixed )
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count - nhostdevs ) ;
else
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
/* Test conflict */
2016-03-02 17:15:07 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
2016-03-02 17:33:18 +03:00
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test: prepare same hostdevs for same driver/domain again " ) ;
2014-03-06 12:08:36 +04:00
if ( ! virHostdevPreparePCIDevices ( mgr , drv_name , dom_name , uuid ,
& hostdevs [ 0 ] , 1 , 0 ) )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test: prepare same hostdevs for same driver, diff domain again " ) ;
2014-03-06 12:08:36 +04:00
if ( ! virHostdevPreparePCIDevices ( mgr , drv_name , " test_domain1 " , uuid ,
& hostdevs [ 1 ] , 1 , 0 ) )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test: prepare same hostdevs for diff driver/domain again " ) ;
2014-03-06 12:08:36 +04:00
if ( ! virHostdevPreparePCIDevices ( mgr , " test_driver1 " , dom_name , uuid ,
& hostdevs [ 2 ] , 1 , 0 ) )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
return ret ;
}
static int
2016-03-18 20:03:53 +03:00
testVirHostdevReAttachPCIHostdevs_managed ( bool mixed )
2014-03-06 12:08:36 +04:00
{
int ret = - 1 ;
2016-03-02 17:33:18 +03:00
size_t active_count , inactive_count , i ;
2014-03-06 12:08:36 +04:00
for ( i = 0 ; i < nhostdevs ; i + + ) {
if ( hostdevs [ i ] - > managed ! = true ) {
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " invalid test " ) ;
2014-03-06 12:08:36 +04:00
return - 1 ;
}
}
2016-03-02 17:15:07 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
2016-03-02 17:33:18 +03:00
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test 0 hostdevs " ) ;
2014-03-06 12:08:36 +04:00
virHostdevReAttachPCIDevices ( mgr , drv_name , dom_name , NULL , 0 , NULL ) ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test >=1 hostdevs " ) ;
2014-03-06 12:08:36 +04:00
virHostdevReAttachPCIDevices ( mgr , drv_name , dom_name ,
hostdevs , nhostdevs , NULL ) ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count - nhostdevs ) ;
2016-03-18 20:03:53 +03:00
/* If testing a mixed roundtrip, devices are added back to the inactive
* list as soon as we detach from the guest */
if ( mixed )
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count + nhostdevs ) ;
else
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
return ret ;
}
static int
2016-03-03 18:13:04 +03:00
testVirHostdevDetachPCINodeDevice ( void )
2014-03-06 12:08:36 +04:00
{
int ret = - 1 ;
2016-03-02 17:33:18 +03:00
size_t active_count , inactive_count , i ;
2014-03-06 12:08:36 +04:00
for ( i = 0 ; i < nhostdevs ; i + + ) {
2016-03-02 17:33:18 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
2016-03-02 17:15:07 +03:00
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2014-03-06 12:08:36 +04:00
if ( virHostdevPCINodeDeviceDetach ( mgr , dev [ i ] ) < 0 )
goto cleanup ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count + 1 ) ;
2014-03-06 12:08:36 +04:00
}
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
return ret ;
}
2016-03-03 18:13:04 +03:00
2014-03-06 12:08:36 +04:00
static int
2016-03-03 18:13:04 +03:00
testVirHostdevResetPCINodeDevice ( void )
2014-03-06 12:08:36 +04:00
{
int ret = - 1 ;
2016-03-02 17:33:18 +03:00
size_t active_count , inactive_count , i ;
2014-03-06 12:08:36 +04:00
for ( i = 0 ; i < nhostdevs ; i + + ) {
2016-03-02 17:33:18 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2014-03-06 12:08:36 +04:00
if ( virHostdevPCINodeDeviceReset ( mgr , dev [ i ] ) < 0 )
goto cleanup ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
}
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
return ret ;
}
static int
2016-03-03 18:13:04 +03:00
testVirHostdevReAttachPCINodeDevice ( void )
2014-03-06 12:08:36 +04:00
{
int ret = - 1 ;
2016-03-02 17:33:18 +03:00
size_t active_count , inactive_count , i ;
2014-03-06 12:08:36 +04:00
for ( i = 0 ; i < nhostdevs ; i + + ) {
2016-03-02 17:33:18 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
2016-03-02 17:15:07 +03:00
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2014-03-06 12:08:36 +04:00
if ( virHostdevPCINodeDeviceReAttach ( mgr , dev [ i ] ) < 0 )
goto cleanup ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count - 1 ) ;
2014-03-06 12:08:36 +04:00
}
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
return ret ;
}
static int
2016-03-03 18:13:04 +03:00
testVirHostdevUpdateActivePCIHostdevs ( void )
2014-03-06 12:08:36 +04:00
{
int ret = - 1 ;
2016-03-02 17:33:18 +03:00
size_t active_count , inactive_count ;
2014-03-06 12:08:36 +04:00
2016-03-02 17:15:07 +03:00
active_count = virPCIDeviceListCount ( mgr - > activePCIHostdevs ) ;
2016-03-02 17:33:18 +03:00
inactive_count = virPCIDeviceListCount ( mgr - > inactivePCIHostdevs ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test 0 hostdevs " ) ;
2014-03-06 12:08:36 +04:00
if ( virHostdevUpdateActivePCIDevices ( mgr , NULL , 0 ,
drv_name , dom_name ) < 0 )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count ) ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
2015-10-27 21:14:01 +03:00
VIR_DEBUG ( " Test >=1 hostdevs " ) ;
2014-03-06 12:08:36 +04:00
if ( virHostdevUpdateActivePCIDevices ( mgr , hostdevs , nhostdevs ,
drv_name , dom_name ) < 0 )
goto cleanup ;
2016-03-02 17:15:07 +03:00
CHECK_LIST_COUNT ( mgr - > activePCIHostdevs , active_count + nhostdevs ) ;
2016-03-02 17:33:18 +03:00
CHECK_LIST_COUNT ( mgr - > inactivePCIHostdevs , inactive_count ) ;
2014-03-06 12:08:36 +04:00
ret = 0 ;
2014-03-25 10:53:44 +04:00
cleanup :
2014-03-06 12:08:36 +04:00
return ret ;
}
2016-03-18 20:03:53 +03:00
/**
* testVirHostdevRoundtripNoGuest :
* @ opaque : unused
*
* Perform a roundtrip without ever assigning devices to the guest .
*
* 1. Detach devices from the host
* 2. Reattach devices to the host
*/
static int
testVirHostdevRoundtripNoGuest ( const void * opaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
if ( testVirHostdevDetachPCINodeDevice ( ) < 0 )
goto out ;
if ( testVirHostdevReAttachPCINodeDevice ( ) < 0 )
goto out ;
ret = 0 ;
out :
return ret ;
}
2016-03-03 18:13:04 +03:00
/**
* testVirHostdevRoundtripUnmanaged :
* @ opaque : unused
*
* Perform a roundtrip with unmanaged devices .
*
* 1. Detach devices from the host
* 2. Attach devices to the guest as unmanaged
* 3. Detach devices from the guest as unmanaged
* 4. Reattach devices to the host
*/
static int
testVirHostdevRoundtripUnmanaged ( const void * opaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
if ( testVirHostdevDetachPCINodeDevice ( ) < 0 )
goto out ;
if ( virHostdevHostSupportsPassthroughKVM ( ) ) {
if ( testVirHostdevPreparePCIHostdevs_unmanaged ( ) < 0 )
goto out ;
if ( testVirHostdevReAttachPCIHostdevs_unmanaged ( ) < 0 )
goto out ;
}
if ( testVirHostdevReAttachPCINodeDevice ( ) < 0 )
goto out ;
ret = 0 ;
out :
return ret ;
}
/**
* testVirHostdevRoundtripManaged :
* @ opaque : unused
*
* Perform a roundtrip with managed devices .
*
* 1. Attach devices to the guest as managed
* 2. Detach devices from the guest as managed
*/
static int
testVirHostdevRoundtripManaged ( const void * opaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
if ( virHostdevHostSupportsPassthroughKVM ( ) ) {
2016-03-18 20:03:53 +03:00
if ( testVirHostdevPreparePCIHostdevs_managed ( false ) < 0 )
2016-03-03 18:13:04 +03:00
goto out ;
2016-03-18 20:03:53 +03:00
if ( testVirHostdevReAttachPCIHostdevs_managed ( false ) < 0 )
2016-03-03 18:13:04 +03:00
goto out ;
}
ret = 0 ;
out :
return ret ;
}
2016-03-18 20:03:53 +03:00
/**
* testVirHostdevRoundtripMixed :
* @ opaque : unused
*
* Perform a roundtrip with managed devices but manually detach the devices
* from the host first .
*
* 1. Detach devices from the host
* 2. Attach devices to the guest as managed
* 3. Detach devices from the guest as managed
* 4. Reattach devices to the host
*/
static int
testVirHostdevRoundtripMixed ( const void * opaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
if ( testVirHostdevDetachPCINodeDevice ( ) < 0 )
goto out ;
if ( virHostdevHostSupportsPassthroughKVM ( ) ) {
if ( testVirHostdevPreparePCIHostdevs_managed ( true ) < 0 )
goto out ;
if ( testVirHostdevReAttachPCIHostdevs_managed ( true ) < 0 )
goto out ;
}
if ( testVirHostdevReAttachPCINodeDevice ( ) < 0 )
goto out ;
ret = 0 ;
out :
return ret ;
}
2016-03-03 18:13:04 +03:00
/**
* testVirHostdevOther :
* @ opaque : unused
*
* Perform other operations on devices .
*
* 1. Reset devices
* 2. Update list of active devices
*/
static int
testVirHostdevOther ( const void * opaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
if ( testVirHostdevResetPCINodeDevice ( ) < 0 )
goto out ;
if ( testVirHostdevUpdateActivePCIHostdevs ( ) < 0 )
goto out ;
ret = 0 ;
out :
return ret ;
}
2015-12-04 15:38:16 +03:00
# define FAKEROOTDIRTEMPLATE abs_builddir " / fakerootdir-XXXXXX"
2014-03-06 12:08:36 +04:00
static int
mymain ( void )
{
int ret = 0 ;
2015-12-04 15:38:16 +03:00
char * fakerootdir ;
2014-03-06 12:08:36 +04:00
2015-12-04 15:38:16 +03:00
if ( VIR_STRDUP_QUIET ( fakerootdir , FAKEROOTDIRTEMPLATE ) < 0 ) {
2014-03-06 12:08:36 +04:00
fprintf ( stderr , " Out of memory \n " ) ;
abort ( ) ;
}
2015-12-04 15:38:16 +03:00
if ( ! mkdtemp ( fakerootdir ) ) {
fprintf ( stderr , " Cannot create fakerootdir " ) ;
2014-03-06 12:08:36 +04:00
abort ( ) ;
}
2015-12-04 15:38:16 +03:00
setenv ( " LIBVIRT_FAKE_ROOT_DIR " , fakerootdir , 1 ) ;
2014-03-06 12:08:36 +04:00
2017-11-03 15:09:47 +03:00
# define DO_TEST(fnc) \
do { \
VIR_DEBUG ( " Testing: %s " , # fnc ) ; \
if ( virTestRun ( # fnc , fnc , NULL ) < 0 ) \
ret = - 1 ; \
2014-03-06 12:08:36 +04:00
} while ( 0 )
if ( myInit ( ) < 0 )
fprintf ( stderr , " Init data structures failed. " ) ;
2016-03-18 20:03:53 +03:00
DO_TEST ( testVirHostdevRoundtripNoGuest ) ;
2016-03-03 18:13:04 +03:00
DO_TEST ( testVirHostdevRoundtripUnmanaged ) ;
DO_TEST ( testVirHostdevRoundtripManaged ) ;
2016-03-18 20:03:53 +03:00
DO_TEST ( testVirHostdevRoundtripMixed ) ;
2016-03-03 18:13:04 +03:00
DO_TEST ( testVirHostdevOther ) ;
2014-03-06 12:08:36 +04:00
myCleanup ( ) ;
if ( getenv ( " LIBVIRT_SKIP_CLEANUP " ) = = NULL )
2015-12-04 15:38:16 +03:00
virFileDeleteTree ( fakerootdir ) ;
2014-03-06 12:08:36 +04:00
2015-12-04 15:38:16 +03:00
VIR_FREE ( fakerootdir ) ;
2014-03-06 12:08:36 +04:00
2014-03-17 13:38:38 +04:00
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
2014-03-06 12:08:36 +04:00
}
2017-03-29 17:45:42 +03:00
VIR_TEST_MAIN_PRELOAD ( mymain , abs_builddir " /.libs/virpcimock.so " )
2014-03-06 12:08:36 +04:00
# else
int
main ( void )
{
return EXIT_AM_SKIP ;
}
# endif