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>
2014-08-22 11:37:51 +02:00
# include <c-ctype.h>
2008-11-21 12:16:08 +00:00
# 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"
2013-10-09 11:18:15 +01:00
# include "virutil.h"
2010-11-16 07:54:17 -07:00
# include "configmake.h"
2013-04-03 12:36:23 +02:00
# include "virstring.h"
2008-11-21 12:16:08 +00:00
2014-02-28 12:16:17 +00:00
VIR_LOG_INIT ( " driver " ) ;
2011-01-21 17:42:07 +00:00
# define DEFAULT_DRIVER_DIR LIBDIR " / libvirt / connection-driver"
2008-11-21 12:16:08 +00:00
# ifdef WITH_DRIVER_MODULES
/* XXX re-implment this for other OS, or use libtools helper lib ? */
2010-03-09 19:22:22 +01:00
# include <dlfcn.h>
2008-11-21 12:16:08 +00:00
void *
virDriverLoadModule ( const char * name )
{
2014-08-22 11:37:51 +02:00
char * modfile = NULL , * regfunc = NULL , * fixedname = NULL ;
char * tmp ;
2008-11-21 12:16:08 +00:00
void * handle = NULL ;
int ( * regsym ) ( void ) ;
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 " ,
" src/.libs " ,
LIBDIR " /libvirt/connection-driver " ,
" LIBVIRT_DRIVER_DIR " ) ) )
2008-11-21 12:16:08 +00:00
return NULL ;
if ( access ( modfile , R_OK ) < 0 ) {
2009-05-08 10:05:56 +00:00
VIR_WARN ( " Module %s not accessible " , modfile ) ;
2008-11-21 12:16:08 +00:00
goto cleanup ;
}
2014-03-05 17:20:50 +00:00
virUpdateSelfLastChanged ( modfile ) ;
2012-04-02 17:23:59 +01:00
handle = dlopen ( modfile , RTLD_NOW | RTLD_GLOBAL ) ;
2008-11-21 12:16:08 +00:00
if ( ! handle ) {
2010-05-20 08:15:46 +02:00
VIR_ERROR ( _ ( " failed to load module %s %s " ) , modfile , dlerror ( ) ) ;
2008-11-21 12:16:08 +00:00
goto cleanup ;
}
2014-08-22 11:37:51 +02:00
if ( VIR_STRDUP_QUIET ( fixedname , name ) < 0 ) {
VIR_ERROR ( _ ( " out of memory " ) ) ;
goto cleanup ;
}
/* convert something_like_this into somethingLikeThis */
while ( ( tmp = strchr ( fixedname , ' _ ' ) ) ) {
memmove ( tmp , tmp + 1 , strlen ( tmp ) ) ;
* tmp = c_toupper ( * tmp ) ;
}
2014-11-13 15:27:11 +01:00
if ( virAsprintfQuiet ( & regfunc , " %sRegister " , fixedname ) < 0 )
2008-11-21 12:16:08 +00:00
goto cleanup ;
regsym = dlsym ( handle , regfunc ) ;
if ( ! regsym ) {
2010-05-20 08:15:46 +02:00
VIR_ERROR ( _ ( " Missing module registration symbol %s " ) , regfunc ) ;
2008-11-21 12:16:08 +00:00
goto cleanup ;
}
if ( ( * regsym ) ( ) < 0 ) {
2010-05-20 08:15:46 +02:00
VIR_ERROR ( _ ( " Failed module registration %s " ) , regfunc ) ;
2008-11-21 12:16:08 +00:00
goto cleanup ;
}
VIR_FREE ( modfile ) ;
VIR_FREE ( regfunc ) ;
2014-08-22 11:37:51 +02:00
VIR_FREE ( fixedname ) ;
2008-11-21 12:16:08 +00:00
return handle ;
2014-03-25 07:57:22 +01:00
cleanup :
2008-11-21 12:16:08 +00:00
VIR_FREE ( modfile ) ;
VIR_FREE ( regfunc ) ;
2014-08-22 11:37:51 +02:00
VIR_FREE ( fixedname ) ;
2008-11-21 12:16:08 +00:00
if ( handle )
dlclose ( handle ) ;
return NULL ;
}
/* XXX unload modules, but we can't until we can unregister libvirt drivers */
# endif