2009-07-28 18:46:53 +04:00
/*
2014-06-27 08:07:46 +04:00
Copyright Red Hat , Inc . 2006 - 2014
2009-07-28 18:46:53 +04:00
This program is free software ; you can redistribute it and / or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation ; either version 2 , or ( at your option ) any
later version .
This program 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
General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; see the file COPYING . If not , write to the
Free Software Foundation , Inc . , 675 Mass Ave , Cambridge ,
MA 0213 9 , USA .
*/
/*
* Author : Lon Hohberger < lhh at redhat . com >
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <signal.h>
# include <string.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/wait.h>
# include <sys/un.h>
# include <sys/socket.h>
# include <sys/select.h>
# include <sys/ioctl.h>
# include <arpa/inet.h>
# include <net/if.h>
# include <netinet/in.h>
# include <netdb.h>
# include <sys/time.h>
# include <fcntl.h>
# include <errno.h>
# include <pthread.h>
2009-09-15 21:27:03 +04:00
# include <libvirt/virterror.h>
2009-07-28 18:46:53 +04:00
# include <nss.h>
# include <libgen.h>
2009-09-01 23:13:53 +04:00
# include <syslog.h>
2009-08-18 00:53:58 +04:00
# include <simpleconfig.h>
2010-01-14 21:38:37 +03:00
# include <static_map.h>
2009-07-28 18:46:53 +04:00
# include <server_plugin.h>
/* Local includes */
# include "xvm.h"
# include "simple_auth.h"
# include "options.h"
# include "mcast.h"
# include "tcp.h"
# include "virt.h"
# include "debug.h"
2010-01-09 02:20:33 +03:00
# include "uuid-test.h"
2009-07-28 18:46:53 +04:00
2009-08-12 21:20:50 +04:00
# define NAME "libvirt"
2017-05-22 21:15:48 +03:00
# define VERSION "0.2"
2009-08-12 21:20:50 +04:00
2009-09-01 23:13:53 +04:00
# define MAGIC 0x1e19317a
struct libvirt_info {
int magic ;
2014-06-27 08:07:46 +04:00
int vp_count ;
virConnectPtr * vp ;
2009-09-01 23:13:53 +04:00
} ;
2009-09-03 18:55:30 +04:00
# define VALIDATE(arg) \
do { \
if ( ! arg | | ( ( struct libvirt_info * ) arg ) - > magic ! = MAGIC ) { \
errno = EINVAL ; \
return - 1 ; \
} \
} while ( 0 )
2009-09-01 23:13:53 +04:00
2009-07-28 18:46:53 +04:00
static inline int
2014-06-27 08:07:46 +04:00
wait_domain ( const char * vm_name , virConnectPtr vp , int timeout )
2009-07-28 18:46:53 +04:00
{
int tries = 0 ;
int response = 1 ;
2011-09-20 19:15:34 +04:00
int ret ;
2009-07-28 18:46:53 +04:00
virDomainPtr vdp ;
virDomainInfo vdi ;
2009-12-08 02:11:25 +03:00
int uuid_check ;
2014-06-27 08:07:46 +04:00
2009-12-08 02:11:25 +03:00
uuid_check = is_uuid ( vm_name ) ;
2009-07-28 18:46:53 +04:00
2009-12-08 02:11:25 +03:00
if ( uuid_check ) {
2009-12-04 01:29:47 +03:00
vdp = virDomainLookupByUUIDString ( vp , ( const char * ) vm_name ) ;
2009-09-01 23:13:53 +04:00
} else {
vdp = virDomainLookupByName ( vp , vm_name ) ;
}
2009-07-28 18:46:53 +04:00
if ( ! vdp )
return 0 ;
/* Check domain liveliness. If the domain is still here,
we return failure , and the client must then retry */
/* XXX On the xen 3.0.4 API, we will be able to guarantee
synchronous virDomainDestroy , so this check will not
be necessary */
do {
2011-09-20 19:15:34 +04:00
if ( + + tries > timeout )
break ;
2009-07-28 18:46:53 +04:00
sleep ( 1 ) ;
2009-12-08 02:11:25 +03:00
if ( uuid_check ) {
2014-06-27 08:07:46 +04:00
vdp = virDomainLookupByUUIDString ( vp , ( const char * ) vm_name ) ;
2009-09-01 23:13:53 +04:00
} else {
vdp = virDomainLookupByName ( vp , vm_name ) ;
}
2009-07-28 18:46:53 +04:00
if ( ! vdp ) {
dbg_printf ( 2 , " Domain no longer exists \n " ) ;
response = 0 ;
break ;
}
memset ( & vdi , 0 , sizeof ( vdi ) ) ;
2011-09-20 19:15:34 +04:00
ret = virDomainGetInfo ( vdp , & vdi ) ;
2009-07-28 18:46:53 +04:00
virDomainFree ( vdp ) ;
2011-09-20 19:15:34 +04:00
if ( ret < 0 )
continue ;
2009-07-28 18:46:53 +04:00
if ( vdi . state = = VIR_DOMAIN_SHUTOFF ) {
dbg_printf ( 2 , " Domain has been shut off \n " ) ;
response = 0 ;
break ;
}
2014-06-27 08:07:46 +04:00
dbg_printf ( 4 , " Domain still exists (state %d) after %d seconds \n " ,
vdi . state , tries ) ;
2009-07-28 18:46:53 +04:00
} while ( 1 ) ;
return response ;
}
static int
libvirt_null ( const char * vm_name , void * priv )
{
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " ENTER %s %s \n " , __FUNCTION__ , vm_name ) ;
2009-07-28 18:46:53 +04:00
printf ( " NULL operation: returning failure \n " ) ;
return 1 ;
}
static int
2014-06-27 08:07:46 +04:00
libvirt_off ( const char * vm_name , const char * src , uint32_t seqno , void * priv )
2009-07-28 18:46:53 +04:00
{
2009-09-01 23:13:53 +04:00
struct libvirt_info * info = ( struct libvirt_info * ) priv ;
2014-06-27 08:07:46 +04:00
virDomainPtr vdp = NULL ;
2009-07-28 18:46:53 +04:00
virDomainInfo vdi ;
2014-06-27 08:07:46 +04:00
virDomainPtr ( * virt_lookup_fn ) ( virConnectPtr , const char * ) ;
2009-07-28 18:46:53 +04:00
int ret = - 1 ;
2014-06-27 08:07:46 +04:00
int i ;
2009-07-28 18:46:53 +04:00
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " ENTER %s %s %u \n " , __FUNCTION__ , vm_name , seqno ) ;
2009-09-01 23:13:53 +04:00
VALIDATE ( info ) ;
2009-07-28 18:46:53 +04:00
2014-06-27 08:07:46 +04:00
if ( is_uuid ( vm_name ) )
virt_lookup_fn = virDomainLookupByUUIDString ;
else
virt_lookup_fn = virDomainLookupByName ;
for ( i = 0 ; i < info - > vp_count ; i + + ) {
vdp = virt_lookup_fn ( info - > vp [ i ] , vm_name ) ;
if ( vdp )
break ;
2009-09-01 23:13:53 +04:00
}
2009-07-28 18:46:53 +04:00
2012-10-27 02:14:45 +04:00
if ( ! vdp ) {
2014-06-27 08:07:46 +04:00
dbg_printf ( 2 , " [libvirt:OFF] Domain %s does not exist \n " , vm_name ) ;
2012-10-08 18:53:13 +04:00
return 1 ;
2009-07-28 18:46:53 +04:00
}
2014-06-27 08:07:46 +04:00
if ( virDomainGetInfo ( vdp , & vdi ) = = 0 & & vdi . state = = VIR_DOMAIN_SHUTOFF ) {
dbg_printf ( 2 , " [libvirt:OFF] Nothing to do - "
" domain %s is already off \n " ,
vm_name ) ;
2012-10-27 02:14:45 +04:00
virDomainFree ( vdp ) ;
return 0 ;
}
2009-09-01 23:13:53 +04:00
syslog ( LOG_NOTICE , " Destroying domain %s \n " , vm_name ) ;
2014-06-27 08:07:46 +04:00
dbg_printf ( 2 , " [libvirt:OFF] Calling virDomainDestroy for %s \n " , vm_name ) ;
2009-07-28 18:46:53 +04:00
ret = virDomainDestroy ( vdp ) ;
2014-06-27 08:07:46 +04:00
virDomainFree ( vdp ) ;
2009-07-28 18:46:53 +04:00
if ( ret < 0 ) {
2014-06-27 08:07:46 +04:00
syslog ( LOG_NOTICE , " Failed to destroy domain %s: %d \n " , vm_name , ret ) ;
dbg_printf ( 2 , " [libvirt:OFF] Failed to destroy domain: %s %d \n " ,
vm_name , ret ) ;
2009-07-28 18:46:53 +04:00
return 1 ;
}
if ( ret ) {
2014-06-27 08:07:46 +04:00
syslog ( LOG_NOTICE , " Domain %s still exists; fencing failed \n " , vm_name ) ;
dbg_printf ( 2 , " [libvirt:OFF] Domain %s still exists; fencing failed \n " ,
vm_name ) ;
2009-07-28 18:46:53 +04:00
return 1 ;
}
2014-06-27 08:07:46 +04:00
dbg_printf ( 2 , " [libvirt:OFF] Success for %s \n " , vm_name ) ;
2009-07-28 18:46:53 +04:00
return 0 ;
}
static int
2014-06-27 08:07:46 +04:00
libvirt_on ( const char * vm_name , const char * src , uint32_t seqno , void * priv )
2009-07-28 18:46:53 +04:00
{
2009-09-15 23:24:56 +04:00
struct libvirt_info * info = ( struct libvirt_info * ) priv ;
2014-06-27 08:07:46 +04:00
virDomainPtr vdp = NULL ;
2009-09-15 23:24:56 +04:00
virDomainInfo vdi ;
2014-06-27 08:07:46 +04:00
virDomainPtr ( * virt_lookup_fn ) ( virConnectPtr , const char * ) ;
2009-09-15 23:24:56 +04:00
int ret = - 1 ;
2014-06-27 08:07:46 +04:00
int i ;
2009-09-15 23:24:56 +04:00
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " ENTER %s %s %u \n " , __FUNCTION__ , vm_name , seqno ) ;
2009-09-15 23:24:56 +04:00
VALIDATE ( info ) ;
2014-06-27 08:07:46 +04:00
if ( is_uuid ( vm_name ) )
virt_lookup_fn = virDomainLookupByUUIDString ;
else
virt_lookup_fn = virDomainLookupByName ;
for ( i = 0 ; i < info - > vp_count ; i + + ) {
vdp = virt_lookup_fn ( info - > vp [ i ] , vm_name ) ;
if ( vdp )
break ;
2009-09-15 23:24:56 +04:00
}
2014-06-27 08:07:46 +04:00
if ( ! vdp ) {
dbg_printf ( 2 , " [libvirt:ON] Domain %s does not exist \n " , vm_name ) ;
return 1 ;
}
2009-07-28 18:46:53 +04:00
2014-06-27 08:07:46 +04:00
if ( virDomainGetInfo ( vdp , & vdi ) = = 0 & & vdi . state ! = VIR_DOMAIN_SHUTOFF ) {
dbg_printf ( 2 , " Nothing to do - domain %s is already running \n " ,
vm_name ) ;
virDomainFree ( vdp ) ;
2009-09-15 23:24:56 +04:00
return 0 ;
}
syslog ( LOG_NOTICE , " Starting domain %s \n " , vm_name ) ;
2014-06-27 08:07:46 +04:00
dbg_printf ( 2 , " [libvirt:ON] Calling virDomainCreate for %s \n " , vm_name ) ;
2009-09-15 23:24:56 +04:00
ret = virDomainCreate ( vdp ) ;
2014-06-27 08:07:46 +04:00
virDomainFree ( vdp ) ;
2009-09-15 23:24:56 +04:00
if ( ret < 0 ) {
2014-06-27 08:07:46 +04:00
syslog ( LOG_NOTICE , " Failed to start domain %s: %d \n " , vm_name , ret ) ;
dbg_printf ( 2 , " [libvirt:ON] virDomainCreate() failed for %s: %d \n " ,
vm_name , ret ) ;
2009-09-15 23:24:56 +04:00
return 1 ;
}
if ( ret ) {
2014-06-27 08:07:46 +04:00
syslog ( LOG_NOTICE , " Domain %s did not start \n " , vm_name ) ;
dbg_printf ( 2 , " [libvirt:ON] Domain %s did not start \n " , vm_name ) ;
2009-09-15 23:24:56 +04:00
return 1 ;
}
2014-06-27 08:07:46 +04:00
syslog ( LOG_NOTICE , " Domain %s started \n " , vm_name ) ;
dbg_printf ( 2 , " [libvirt:ON] Success for %s \n " , vm_name ) ;
2009-09-15 23:24:56 +04:00
return 0 ;
2009-07-28 18:46:53 +04:00
}
static int
libvirt_devstatus ( void * priv )
{
dbg_printf ( 5 , " %s --- \n " , __FUNCTION__ ) ;
if ( priv )
return 0 ;
return 1 ;
}
static int
libvirt_status ( const char * vm_name , void * priv )
{
2009-09-01 23:13:53 +04:00
struct libvirt_info * info = ( struct libvirt_info * ) priv ;
2014-06-27 08:07:46 +04:00
virDomainPtr vdp = NULL ;
2009-07-28 18:46:53 +04:00
virDomainInfo vdi ;
int ret = 0 ;
2014-06-27 08:07:46 +04:00
int i ;
virDomainPtr ( * virt_lookup_fn ) ( virConnectPtr , const char * ) ;
2009-07-28 18:46:53 +04:00
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " ENTER %s %s \n " , __FUNCTION__ , vm_name ) ;
2009-09-01 23:13:53 +04:00
VALIDATE ( info ) ;
2009-07-28 18:46:53 +04:00
2014-06-27 08:07:46 +04:00
if ( is_uuid ( vm_name ) )
virt_lookup_fn = virDomainLookupByUUIDString ;
else
virt_lookup_fn = virDomainLookupByName ;
for ( i = 0 ; i < info - > vp_count ; i + + ) {
vdp = virt_lookup_fn ( info - > vp [ i ] , vm_name ) ;
if ( vdp )
break ;
}
if ( ! vdp ) {
dbg_printf ( 2 , " [libvirt:STATUS] Unknown VM %s - return OFF \n " , vm_name ) ;
return RESP_OFF ;
2009-09-01 23:13:53 +04:00
}
2009-07-28 18:46:53 +04:00
2014-06-27 08:07:46 +04:00
if ( virDomainGetInfo ( vdp , & vdi ) = = 0 & & vdi . state = = VIR_DOMAIN_SHUTOFF ) {
dbg_printf ( 2 , " [libvirt:STATUS] VM %s is OFF \n " , vm_name ) ;
2010-01-15 16:06:34 +03:00
ret = RESP_OFF ;
2009-07-28 18:46:53 +04:00
}
if ( vdp )
virDomainFree ( vdp ) ;
return ret ;
}
static int
2014-06-27 08:07:46 +04:00
libvirt_reboot ( const char * vm_name , const char * src , uint32_t seqno , void * priv )
2009-07-28 18:46:53 +04:00
{
2009-09-01 23:13:53 +04:00
struct libvirt_info * info = ( struct libvirt_info * ) priv ;
2014-06-27 08:07:46 +04:00
virDomainPtr vdp = NULL , nvdp ;
2009-07-28 18:46:53 +04:00
virDomainInfo vdi ;
char * domain_desc ;
2014-06-27 08:07:46 +04:00
virConnectPtr vcp = NULL ;
virDomainPtr ( * virt_lookup_fn ) ( virConnectPtr , const char * ) ;
2009-07-28 18:46:53 +04:00
int ret ;
2014-06-27 08:07:46 +04:00
int i ;
2009-07-28 18:46:53 +04:00
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " ENTER %s %s %u \n " , __FUNCTION__ , vm_name , seqno ) ;
2009-09-01 23:13:53 +04:00
VALIDATE ( info ) ;
2014-06-27 08:07:46 +04:00
if ( is_uuid ( vm_name ) )
virt_lookup_fn = virDomainLookupByUUIDString ;
else
virt_lookup_fn = virDomainLookupByName ;
for ( i = 0 ; i < info - > vp_count ; i + + ) {
vdp = virt_lookup_fn ( info - > vp [ i ] , vm_name ) ;
if ( vdp ) {
vcp = info - > vp [ i ] ;
break ;
}
2009-09-01 23:13:53 +04:00
}
2009-07-28 18:46:53 +04:00
2014-06-27 08:07:46 +04:00
if ( ! vdp | | ! vcp ) {
dbg_printf ( 2 ,
" [libvirt:REBOOT] Nothing to do - domain %s does not exist \n " ,
vm_name ) ;
2012-10-08 18:53:13 +04:00
return 1 ;
2009-07-28 18:46:53 +04:00
}
2014-06-27 08:07:46 +04:00
if ( virDomainGetInfo ( vdp , & vdi ) = = 0 & & vdi . state = = VIR_DOMAIN_SHUTOFF ) {
dbg_printf ( 2 , " [libvirt:REBOOT] Nothing to do - domain %s is off \n " ,
vm_name ) ;
2012-10-27 02:14:45 +04:00
virDomainFree ( vdp ) ;
return 0 ;
}
2009-09-01 23:13:53 +04:00
syslog ( LOG_NOTICE , " Rebooting domain %s \n " , vm_name ) ;
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " [libvirt:REBOOT] Rebooting domain %s... \n " , vm_name ) ;
2009-07-28 18:46:53 +04:00
domain_desc = virDomainGetXMLDesc ( vdp , 0 ) ;
if ( ! domain_desc ) {
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " [libvirt:REBOOT] Failed getting domain description "
" from libvirt for %s... \n " , vm_name ) ;
2009-07-28 18:46:53 +04:00
}
2014-06-27 08:07:46 +04:00
dbg_printf ( 2 , " [libvirt:REBOOT] Calling virDomainDestroy(%p) for %s \n " ,
vdp , vm_name ) ;
2009-07-28 18:46:53 +04:00
ret = virDomainDestroy ( vdp ) ;
if ( ret < 0 ) {
2014-06-27 08:07:46 +04:00
dbg_printf ( 2 ,
" [libvirt:REBOOT] virDomainDestroy() failed for %s: %d/%d \n " ,
vm_name , ret , errno ) ;
if ( domain_desc )
free ( domain_desc ) ;
2009-07-28 18:46:53 +04:00
virDomainFree ( vdp ) ;
return 1 ;
}
2014-06-27 08:07:46 +04:00
ret = wait_domain ( vm_name , vcp , 15 ) ;
2009-07-28 18:46:53 +04:00
if ( ret ) {
2014-06-27 08:07:46 +04:00
syslog ( LOG_NOTICE , " Domain %s still exists; fencing failed \n " , vm_name ) ;
dbg_printf ( 2 ,
" [libvirt:REBOOT] Domain %s still exists; fencing failed \n " ,
vm_name ) ;
2009-07-28 18:46:53 +04:00
if ( domain_desc )
free ( domain_desc ) ;
2014-06-27 08:07:46 +04:00
virDomainFree ( vdp ) ;
2009-07-28 18:46:53 +04:00
return 1 ;
}
2014-06-27 08:07:46 +04:00
2009-07-28 18:46:53 +04:00
if ( ! domain_desc )
return 0 ;
/* 'on' is not a failure */
ret = 0 ;
dbg_printf ( 3 , " [[ XML Domain Info ]] \n " ) ;
dbg_printf ( 3 , " %s \n [[ XML END ]] \n " , domain_desc ) ;
2014-06-27 08:07:46 +04:00
dbg_printf ( 2 , " [libvirt:REBOOT] Calling virDomainCreateLinux() for %s \n " ,
vm_name ) ;
nvdp = virDomainCreateLinux ( vcp , domain_desc , 0 ) ;
2009-07-28 18:46:53 +04:00
if ( nvdp = = NULL ) {
/* More recent versions of libvirt or perhaps the
* KVM back - end do not let you create a domain from
* XML if there is already a defined domain description
* with the same name that it knows about . You must
* then call virDomainCreate ( ) */
2014-06-27 08:07:46 +04:00
dbg_printf ( 2 ,
" [libvirt:REBOOT] virDomainCreateLinux() failed for %s; "
" Trying virDomainCreate() \n " ,
vm_name ) ;
2009-07-28 18:46:53 +04:00
if ( virDomainCreate ( vdp ) < 0 ) {
2014-06-27 08:07:46 +04:00
syslog ( LOG_NOTICE , " Could not restart %s \n " , vm_name ) ;
dbg_printf ( 1 , " [libvirt:REBOOT] Failed to recreate guest %s! \n " ,
vm_name ) ;
2009-07-28 18:46:53 +04:00
}
}
free ( domain_desc ) ;
2014-06-27 08:07:46 +04:00
virDomainFree ( vdp ) ;
2009-07-28 18:46:53 +04:00
return ret ;
}
2009-12-07 20:55:48 +03:00
static int
libvirt_hostlist ( hostlist_callback callback , void * arg , void * priv )
{
struct libvirt_info * info = ( struct libvirt_info * ) priv ;
2014-06-27 08:07:46 +04:00
int i ;
2009-12-07 20:55:48 +03:00
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " ENTER %s \n " , __FUNCTION__ ) ;
2009-12-07 20:55:48 +03:00
VALIDATE ( info ) ;
2014-06-27 08:07:46 +04:00
for ( i = 0 ; i < info - > vp_count ; i + + ) {
int x ;
virt_list_t * vl ;
2009-12-07 20:55:48 +03:00
2014-06-27 08:07:46 +04:00
vl = vl_get ( info - > vp [ i ] , 1 ) ;
if ( ! vl )
continue ;
for ( x = 0 ; x < vl - > vm_count ; x + + ) {
callback ( vl - > vm_states [ x ] . v_name ,
vl - > vm_states [ x ] . v_uuid ,
vl - > vm_states [ x ] . v_state . s_state , arg ) ;
2009-12-07 20:55:48 +03:00
2014-06-27 08:07:46 +04:00
dbg_printf ( 10 , " [libvirt:HOSTLIST] Sent %s %s %d \n " ,
vl - > vm_states [ x ] . v_name ,
vl - > vm_states [ x ] . v_uuid ,
vl - > vm_states [ x ] . v_state . s_state ) ;
}
vl_free ( vl ) ;
}
2009-12-07 20:55:48 +03:00
return 0 ;
}
2009-08-12 21:20:50 +04:00
static int
2009-08-28 22:12:46 +04:00
libvirt_init ( backend_context_t * c , config_object_t * config )
2009-07-28 18:46:53 +04:00
{
virConnectPtr vp ;
2009-08-18 00:53:58 +04:00
char value [ 256 ] ;
2009-09-01 23:13:53 +04:00
struct libvirt_info * info = NULL ;
2014-06-27 08:07:46 +04:00
int i = 0 ;
2009-07-28 18:46:53 +04:00
2009-09-01 23:13:53 +04:00
info = malloc ( sizeof ( * info ) ) ;
if ( ! info )
return - 1 ;
2014-06-27 08:07:46 +04:00
dbg_printf ( 5 , " ENTER [%s:%d %s] \n " , __FILE__ , __LINE__ , __FUNCTION__ ) ;
2009-09-01 23:13:53 +04:00
memset ( info , 0 , sizeof ( * info ) ) ;
2009-09-15 23:17:14 +04:00
# ifdef _MODULE
2014-06-27 08:07:46 +04:00
if ( sc_get ( config , " fence_virtd/@debug " , value , sizeof ( value ) ) = = 0 )
2009-09-04 01:45:38 +04:00
dset ( atoi ( value ) ) ;
2009-09-15 23:17:14 +04:00
# endif
2009-09-04 01:45:38 +04:00
2014-06-27 08:07:46 +04:00
do {
virConnectPtr * vpl = NULL ;
char conf_attr [ 256 ] ;
char * uri ;
if ( i ! = 0 ) {
snprintf ( conf_attr , sizeof ( conf_attr ) ,
" backends/libvirt/@uri%d " , i ) ;
} else
snprintf ( conf_attr , sizeof ( conf_attr ) , " backends/libvirt/@uri " ) ;
+ + i ;
if ( sc_get ( config , conf_attr , value , sizeof ( value ) ) ! = 0 )
break ;
uri = value ;
vp = virConnectOpen ( uri ) ;
if ( ! vp ) {
dbg_printf ( 1 , " [libvirt:INIT] Failed to connect to URI: %s \n " , uri ) ;
continue ;
2009-09-01 23:39:01 +04:00
}
2009-08-18 00:53:58 +04:00
2014-06-27 08:07:46 +04:00
vpl = realloc ( info - > vp , sizeof ( * info - > vp ) * ( info - > vp_count + 1 ) ) ;
if ( ! vpl ) {
dbg_printf ( 1 , " [libvirt:INIT] Out of memory allocating URI: %s \n " ,
uri ) ;
virConnectClose ( vp ) ;
continue ;
}
info - > vp = vpl ;
info - > vp [ info - > vp_count + + ] = vp ;
if ( i > 1 )
dbg_printf ( 1 , " [libvirt:INIT] Added URI%d %s \n " , i - 1 , uri ) ;
else
dbg_printf ( 1 , " [libvirt:INIT] Added URI %s \n " , uri ) ;
} while ( 1 ) ;
if ( info - > vp_count < 1 ) {
dbg_printf ( 1 , " [libvirt:INIT] Could not connect to any hypervisors \n " ) ;
if ( info - > vp )
free ( info - > vp ) ;
2009-09-01 23:13:53 +04:00
free ( info ) ;
2009-07-28 18:46:53 +04:00
return - 1 ;
2009-09-01 23:13:53 +04:00
}
info - > magic = MAGIC ;
* c = ( void * ) info ;
2009-07-28 18:46:53 +04:00
return 0 ;
}
2009-08-12 21:20:50 +04:00
static int
2009-08-28 22:12:46 +04:00
libvirt_shutdown ( backend_context_t c )
2009-07-28 18:46:53 +04:00
{
2009-09-01 23:13:53 +04:00
struct libvirt_info * info = ( struct libvirt_info * ) c ;
2014-06-27 08:07:46 +04:00
int i ;
int ret = 0 ;
2009-09-01 23:13:53 +04:00
VALIDATE ( info ) ;
2014-06-27 08:07:46 +04:00
for ( i = 0 ; i < info - > vp_count ; i + + ) {
if ( virConnectClose ( info - > vp [ i ] ) < 0 )
ret = - errno ;
2009-09-01 23:13:53 +04:00
}
2014-06-27 08:07:46 +04:00
free ( info - > vp ) ;
2010-01-15 02:46:21 +03:00
free ( info ) ;
2014-06-27 08:07:46 +04:00
return ret ;
2009-07-28 18:46:53 +04:00
}
2009-08-12 21:20:50 +04:00
static fence_callbacks_t libvirt_callbacks = {
2009-07-28 18:46:53 +04:00
. null = libvirt_null ,
. off = libvirt_off ,
. on = libvirt_on ,
. reboot = libvirt_reboot ,
. status = libvirt_status ,
2009-12-07 20:55:48 +03:00
. devstatus = libvirt_devstatus ,
. hostlist = libvirt_hostlist
2009-07-28 18:46:53 +04:00
} ;
2009-08-12 21:20:50 +04:00
2009-09-02 00:22:30 +04:00
static backend_plugin_t libvirt_plugin = {
2009-08-12 21:20:50 +04:00
. name = NAME ,
. version = VERSION ,
. callbacks = & libvirt_callbacks ,
. init = libvirt_init ,
. cleanup = libvirt_shutdown ,
} ;
2009-08-17 17:58:06 +04:00
# ifdef _MODULE
double
BACKEND_VER_SYM ( void )
{
return PLUGIN_VERSION_BACKEND ;
}
2009-09-02 00:22:30 +04:00
const backend_plugin_t *
2009-08-17 17:58:06 +04:00
BACKEND_INFO_SYM ( void )
{
return & libvirt_plugin ;
}
# else
2009-08-12 21:20:50 +04:00
static void __attribute__ ( ( constructor ) )
2009-08-17 17:58:06 +04:00
libvirt_register_plugin ( void )
2009-08-12 21:20:50 +04:00
{
2009-09-15 23:17:14 +04:00
plugin_reg_backend ( & libvirt_plugin ) ;
2009-08-12 21:20:50 +04:00
}
# endif