2008-11-21 12:16:08 +00:00
/*
* driver . c : Helpers for loading drivers
*
2011-04-11 16:25:25 -06:00
* Copyright ( C ) 2006 - 2011 Red Hat , Inc .
2008-11-21 12:16:08 +00: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
2012-09-20 16:30:55 -06:00
* License along with this library . If not , see
2012-07-21 18:06:23 +08:00
* < http : //www.gnu.org/licenses/>.
2008-11-21 12:16:08 +00:00
*
*/
# include <config.h>
# include <unistd.h>
# include "driver.h"
2012-12-12 18:06:53 +00:00
# include "viralloc.h"
2014-04-24 16:45:49 +01:00
# include "virfile.h"
2012-12-12 17:59:27 +00:00
# include "virlog.h"
2010-11-16 07:54:17 -07:00
# include "configmake.h"
2008-11-21 12:16:08 +00:00
2014-02-28 12:16:17 +00:00
VIR_LOG_INIT ( " driver " ) ;
2008-11-21 12:16:08 +00:00
2016-09-22 00:47:30 +05:30
/* XXX re-implement this for other OS, or use libtools helper lib ? */
2008-11-21 12:16:08 +00:00
2017-07-26 21:31:47 +02:00
# include <dlfcn.h>
# define DEFAULT_DRIVER_DIR LIBDIR " / libvirt / connection-driver"
2008-11-21 12:16:08 +00:00
2017-01-18 16:44:20 +01:00
static void *
virDriverLoadModuleFile ( const char * file )
{
void * handle = NULL ;
VIR_DEBUG ( " Load module file '%s' " , file ) ;
if ( access ( file , R_OK ) < 0 ) {
VIR_INFO ( " Module %s not accessible " , file ) ;
return NULL ;
}
virUpdateSelfLastChanged ( file ) ;
if ( ! ( handle = dlopen ( file , RTLD_NOW | RTLD_GLOBAL ) ) )
VIR_ERROR ( _ ( " failed to load module %s %s " ) , file , dlerror ( ) ) ;
return handle ;
}
static void *
virDriverLoadModuleFunc ( void * handle ,
const char * funcname )
{
void * regsym ;
VIR_DEBUG ( " Lookup function '%s' " , funcname ) ;
if ( ! ( regsym = dlsym ( handle , funcname ) ) )
VIR_ERROR ( _ ( " Missing module registration symbol %s " ) , funcname ) ;
return regsym ;
}
/**
* virDriverLoadModuleFull :
* @ path : filename of module to load
* @ regfunc : name of the function that registers the module
* @ handle : Returns handle of the loaded library if not NULL
*
* Loads a loadable module named @ path and calls the
* registration function @ regfunc . If @ handle is not NULL the handle is returned
* in the variable . Otherwise the handle is leaked so that the module stays
* loaded forever .
*
* The module is automatically looked up in the appropriate place ( git or
* installed directory ) .
*
* Returns 0 on success , 1 if the module was not found and - 1 on any error .
*/
int
virDriverLoadModuleFull ( const char * path ,
const char * regfunc ,
void * * handle )
{
void * rethandle = NULL ;
int ( * regsym ) ( void ) ;
int ret = - 1 ;
if ( ! ( rethandle = virDriverLoadModuleFile ( path ) ) ) {
ret = 1 ;
goto cleanup ;
}
if ( ! ( regsym = virDriverLoadModuleFunc ( rethandle , regfunc ) ) )
goto cleanup ;
if ( ( * regsym ) ( ) < 0 ) {
VIR_ERROR ( _ ( " Failed module registration %s " ) , regfunc ) ;
goto cleanup ;
}
if ( handle )
VIR_STEAL_PTR ( * handle , rethandle ) ;
else
rethandle = NULL ;
ret = 0 ;
cleanup :
if ( rethandle )
dlclose ( rethandle ) ;
return ret ;
}
2017-01-26 14:57:41 +01:00
int
virDriverLoadModule ( const char * name ,
const char * regfunc )
2008-11-21 12:16:08 +00:00
{
2017-01-18 16:44:20 +01:00
char * modfile = NULL ;
2017-01-26 14:57:41 +01:00
int ret ;
2008-11-21 12:16:08 +00:00
2011-02-16 16:37:57 -07:00
VIR_DEBUG ( " Module load %s " , name ) ;
2008-11-21 12:16:08 +00:00
2014-04-24 16:45:49 +01:00
if ( ! ( modfile = virFileFindResourceFull ( name ,
" libvirt_driver_ " ,
" .so " ,
2015-02-13 14:25:27 +01:00
abs_topbuilddir " /src/.libs " ,
2015-04-01 12:38:42 +02:00
DEFAULT_DRIVER_DIR ,
2014-04-24 16:45:49 +01:00
" LIBVIRT_DRIVER_DIR " ) ) )
2017-01-26 14:57:41 +01:00
return 1 ;
2008-11-21 12:16:08 +00:00
2017-01-26 14:57:41 +01:00
ret = virDriverLoadModuleFull ( modfile , regfunc , NULL ) ;
2008-11-21 12:16:08 +00:00
VIR_FREE ( modfile ) ;
2017-01-26 14:57:41 +01:00
return ret ;
2008-11-21 12:16:08 +00:00
}
/* XXX unload modules, but we can't until we can unregister libvirt drivers */