2013-10-23 17:44:40 +04:00
/*
* Copyright ( C ) 2013 Red Hat , Inc .
*
* 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 : Michal Privoznik < mprivozn @ redhat . com >
*/
# include <config.h>
# include "testutils.h"
# ifdef __linux__
# include <stdlib.h>
# include <stdio.h>
# include <sys / types.h>
# include <sys / stat.h>
# include <fcntl.h>
# include <virpci.h>
# define VIR_FROM_THIS VIR_FROM_NONE
static int
testVirPCIDeviceNew ( const void * opaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
virPCIDevicePtr dev ;
const char * devName ;
if ( ! ( dev = virPCIDeviceNew ( 0 , 0 , 0 , 0 ) ) )
goto cleanup ;
devName = virPCIDeviceGetName ( dev ) ;
if ( STRNEQ ( devName , " 0000:00:00.0 " ) ) {
virReportError ( VIR_ERR_INTERNAL_ERROR ,
" PCI device name mismatch: %s, expecting %s " ,
devName , " 0000:00:00.0 " ) ;
goto cleanup ;
}
ret = 0 ;
cleanup :
virPCIDeviceFree ( dev ) ;
return ret ;
}
2013-10-23 19:55:02 +04:00
# define CHECK_LIST_COUNT(list, cnt) \
if ( ( count = virPCIDeviceListCount ( list ) ) ! = cnt ) { \
virReportError ( VIR_ERR_INTERNAL_ERROR , \
" Unexpected count of items in " # list " : %d, " \
2013-11-05 18:07:49 +04:00
" expecting %zu " , count , ( size_t ) cnt ) ; \
2013-10-23 19:55:02 +04:00
goto cleanup ; \
}
static int
testVirPCIDeviceDetach ( const void * oaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
2013-11-05 18:07:49 +04:00
virPCIDevicePtr dev [ ] = { NULL , NULL , NULL } ;
size_t i , nDev = ARRAY_CARDINALITY ( dev ) ;
2013-10-23 19:55:02 +04:00
virPCIDeviceListPtr activeDevs = NULL , inactiveDevs = NULL ;
int count ;
2013-11-05 18:07:49 +04:00
if ( ! ( activeDevs = virPCIDeviceListNew ( ) ) | |
2013-10-23 19:55:02 +04:00
! ( inactiveDevs = virPCIDeviceListNew ( ) ) )
goto cleanup ;
CHECK_LIST_COUNT ( activeDevs , 0 ) ;
CHECK_LIST_COUNT ( inactiveDevs , 0 ) ;
2013-11-05 18:07:49 +04:00
for ( i = 0 ; i < nDev ; i + + ) {
if ( ! ( dev [ i ] = virPCIDeviceNew ( 0 , 0 , i + 1 , 0 ) ) | |
virPCIDeviceSetStubDriver ( dev [ i ] , " pci-stub " ) < 0 )
goto cleanup ;
2013-10-23 19:55:02 +04:00
2013-11-05 18:07:49 +04:00
if ( virPCIDeviceDetach ( dev [ i ] , activeDevs , inactiveDevs ) < 0 )
goto cleanup ;
2013-10-23 19:55:02 +04:00
2013-11-05 18:07:49 +04:00
CHECK_LIST_COUNT ( activeDevs , 0 ) ;
CHECK_LIST_COUNT ( inactiveDevs , i + 1 ) ;
}
ret = 0 ;
cleanup :
for ( i = 0 ; i < nDev ; i + + )
virPCIDeviceFree ( dev [ i ] ) ;
virObjectUnref ( activeDevs ) ;
virObjectUnref ( inactiveDevs ) ;
return ret ;
}
2013-10-23 19:55:02 +04:00
2013-11-05 18:07:49 +04:00
static int
testVirPCIDeviceReset ( const void * opaque ATTRIBUTE_UNUSED )
{
int ret = - 1 ;
virPCIDevicePtr dev [ ] = { NULL , NULL , NULL } ;
size_t i , nDev = ARRAY_CARDINALITY ( dev ) ;
virPCIDeviceListPtr activeDevs = NULL , inactiveDevs = NULL ;
int count ;
if ( ! ( activeDevs = virPCIDeviceListNew ( ) ) | |
! ( inactiveDevs = virPCIDeviceListNew ( ) ) )
2013-10-31 15:05:20 +04:00
goto cleanup ;
CHECK_LIST_COUNT ( activeDevs , 0 ) ;
2013-11-05 18:07:49 +04:00
CHECK_LIST_COUNT ( inactiveDevs , 0 ) ;
for ( i = 0 ; i < nDev ; i + + ) {
if ( ! ( dev [ i ] = virPCIDeviceNew ( 0 , 0 , i + 1 , 0 ) ) | |
virPCIDeviceSetStubDriver ( dev [ i ] , " pci-stub " ) < 0 )
goto cleanup ;
if ( virPCIDeviceReset ( dev [ i ] , activeDevs , inactiveDevs ) < 0 )
goto cleanup ;
}
2013-10-31 15:05:20 +04:00
2013-10-23 19:55:02 +04:00
ret = 0 ;
cleanup :
2013-11-05 18:07:49 +04:00
for ( i = 0 ; i < nDev ; i + + )
virPCIDeviceFree ( dev [ i ] ) ;
2013-10-23 19:55:02 +04:00
virObjectUnref ( activeDevs ) ;
virObjectUnref ( inactiveDevs ) ;
return ret ;
}
2013-10-31 14:57:56 +04:00
static int
2013-11-05 18:07:49 +04:00
testVirPCIDeviceReattach ( const void * opaque ATTRIBUTE_UNUSED )
2013-10-31 14:57:56 +04:00
{
int ret = - 1 ;
2013-11-05 18:07:49 +04:00
virPCIDevicePtr dev [ ] = { NULL , NULL , NULL } ;
size_t i , nDev = ARRAY_CARDINALITY ( dev ) ;
2013-10-31 14:57:56 +04:00
virPCIDeviceListPtr activeDevs = NULL , inactiveDevs = NULL ;
int count ;
2013-11-05 18:07:49 +04:00
if ( ! ( activeDevs = virPCIDeviceListNew ( ) ) | |
2013-10-31 14:57:56 +04:00
! ( inactiveDevs = virPCIDeviceListNew ( ) ) )
goto cleanup ;
2013-11-05 18:07:49 +04:00
for ( i = 0 ; i < nDev ; i + + ) {
if ( ! ( dev [ i ] = virPCIDeviceNew ( 0 , 0 , i + 1 , 0 ) ) )
goto cleanup ;
2013-10-31 14:57:56 +04:00
2013-11-05 18:07:49 +04:00
if ( virPCIDeviceListAdd ( inactiveDevs , dev [ i ] ) < 0 ) {
virPCIDeviceFree ( dev [ i ] ) ;
goto cleanup ;
}
2013-10-31 14:57:56 +04:00
2013-11-05 18:07:49 +04:00
CHECK_LIST_COUNT ( activeDevs , 0 ) ;
CHECK_LIST_COUNT ( inactiveDevs , i + 1 ) ;
2013-10-31 14:57:56 +04:00
2013-11-05 18:07:49 +04:00
if ( virPCIDeviceSetStubDriver ( dev [ i ] , " pci-stub " ) < 0 )
goto cleanup ;
}
2013-10-31 14:57:56 +04:00
2013-10-31 15:05:20 +04:00
CHECK_LIST_COUNT ( activeDevs , 0 ) ;
2013-11-05 18:07:49 +04:00
CHECK_LIST_COUNT ( inactiveDevs , nDev ) ;
2013-10-31 15:05:20 +04:00
2013-11-05 18:07:49 +04:00
for ( i = 0 ; i < nDev ; i + + ) {
if ( virPCIDeviceReattach ( dev [ i ] , activeDevs , inactiveDevs ) < 0 )
goto cleanup ;
2013-10-31 15:05:20 +04:00
2013-11-05 18:07:49 +04:00
CHECK_LIST_COUNT ( activeDevs , 0 ) ;
CHECK_LIST_COUNT ( inactiveDevs , nDev - i - 1 ) ;
}
2013-10-31 14:57:56 +04:00
ret = 0 ;
cleanup :
virObjectUnref ( activeDevs ) ;
virObjectUnref ( inactiveDevs ) ;
return ret ;
}
2013-11-05 18:07:49 +04:00
2013-12-24 22:07:27 +04:00
struct testPCIDevData {
unsigned int domain ;
unsigned int bus ;
unsigned int slot ;
unsigned int function ;
} ;
static int
testVirPCIDeviceIsAssignable ( const void * opaque )
{
const struct testPCIDevData * data = opaque ;
int ret = - 1 ;
virPCIDevicePtr dev ;
if ( ! ( dev = virPCIDeviceNew ( data - > domain , data - > bus , data - > slot , data - > function ) ) )
goto cleanup ;
if ( virPCIDeviceIsAssignable ( dev , true ) )
ret = 0 ;
virPCIDeviceFree ( dev ) ;
cleanup :
return ret ;
}
2013-11-05 18:07:49 +04:00
# define FAKESYSFSDIRTEMPLATE abs_builddir " / fakesysfsdir-XXXXXX"
2013-10-23 17:44:40 +04:00
static int
mymain ( void )
{
int ret = 0 ;
char * fakesysfsdir ;
if ( VIR_STRDUP_QUIET ( fakesysfsdir , FAKESYSFSDIRTEMPLATE ) < 0 ) {
fprintf ( stderr , " Out of memory \n " ) ;
abort ( ) ;
}
if ( ! mkdtemp ( fakesysfsdir ) ) {
fprintf ( stderr , " Cannot create fakesysfsdir " ) ;
abort ( ) ;
}
setenv ( " LIBVIRT_FAKE_SYSFS_DIR " , fakesysfsdir , 1 ) ;
# define DO_TEST(fnc) \
do { \
if ( virtTestRun ( # fnc , fnc , NULL ) < 0 ) \
ret = - 1 ; \
} while ( 0 )
2013-12-24 22:07:27 +04:00
# define DO_TEST_PCI(fnc, domain, bus, slot, function) \
do { \
struct testPCIDevData data = { domain , bus , slot , function } ; \
if ( virtTestRun ( # fnc , fnc , & data ) < 0 ) \
ret = - 1 ; \
} while ( 0 )
2013-10-23 17:44:40 +04:00
DO_TEST ( testVirPCIDeviceNew ) ;
2013-10-23 19:55:02 +04:00
DO_TEST ( testVirPCIDeviceDetach ) ;
2013-11-05 18:07:49 +04:00
DO_TEST ( testVirPCIDeviceReset ) ;
2013-10-31 14:57:56 +04:00
DO_TEST ( testVirPCIDeviceReattach ) ;
2013-12-24 22:07:27 +04:00
DO_TEST_PCI ( testVirPCIDeviceIsAssignable , 5 , 0x90 , 1 , 0 ) ;
DO_TEST_PCI ( testVirPCIDeviceIsAssignable , 1 , 1 , 0 , 0 ) ;
2013-10-23 17:44:40 +04:00
if ( getenv ( " LIBVIRT_SKIP_CLEANUP " ) = = NULL )
virFileDeleteTree ( fakesysfsdir ) ;
VIR_FREE ( fakesysfsdir ) ;
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
}
VIRT_TEST_MAIN_PRELOAD ( mymain , abs_builddir " /.libs/virpcimock.so " )
# else
int
main ( void )
{
return EXIT_AM_SKIP ;
}
# endif