2007-02-14 04:40:09 +03:00
/*
2009-09-16 15:37:26 +04:00
* libvirtd . c : daemon start of day , guest process & i / o management
2007-02-14 04:40:09 +03:00
*
2011-02-17 02:37:57 +03:00
* Copyright ( C ) 2006 - 2011 Red Hat , Inc .
2007-02-14 04:40:09 +03:00
* Copyright ( C ) 2006 Daniel P . Berrange
*
* 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 , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*
* Author : Daniel P . Berrange < berrange @ redhat . com >
*/
2008-01-29 21:15:54 +03:00
# include <config.h>
2007-02-14 18:42:55 +03:00
2007-02-14 04:40:09 +03:00
# include <unistd.h>
# include <fcntl.h>
2011-05-16 21:13:11 +04:00
# include <sys/wait.h>
# include <sys/stat.h>
2007-02-14 04:40:09 +03:00
# include <getopt.h>
2011-05-16 21:13:11 +04:00
# include <stdlib.h>
2007-09-19 06:28:01 +04:00
# include <grp.h>
2010-11-16 22:01:37 +03:00
# include <locale.h>
2007-04-11 03:17:46 +04:00
2008-11-05 02:22:06 +03:00
# include "libvirt_internal.h"
2009-02-05 19:28:30 +03:00
# include "virterror_internal.h"
2010-11-09 23:48:48 +03:00
# include "files.h"
Standardize use of header files, making internal.h primary.
* qemud/internal.h, qemud/qemud.h: Rename this file so it
doesn't conflict with src/internal.h.
* HACKING: Document how header files should be used.
* qemud/Makefile.am: Add src/ directory to includes.
* qemud/event.c, qemud/mdns.c, qemud/qemud.c, qemud/remote.c,
qemud/remote_protocol.c, qemud/remote_protocol.h,
qemud/remote_protocol.x, src/buf.c, src/libvirt.c,
src/nodeinfo.c, src/qemu_conf.c, src/qemu_driver.c,
src/stats_linux.c, src/storage_backend.c, src/storage_backend_fs.c,
src/storage_backend_iscsi.c, src/storage_backend_logical.c,
src/storage_conf.c, src/storage_driver.c, src/util.c,
src/util.h, src/virsh.c, src/virterror.c, src/xend_internal.c,
src/xml.c, tests/reconnect.c, tests/xmlrpctest.c,
tests/qparamtest.c: Standardize use of header files.
* docs/*, po/*: Rebuild docs.
2008-05-23 12:24:41 +04:00
2009-02-09 20:52:38 +03:00
# define VIR_FROM_THIS VIR_FROM_QEMU
2009-09-16 15:37:26 +04:00
# include "libvirtd.h"
2009-07-10 15:20:03 +04:00
Standardize use of header files, making internal.h primary.
* qemud/internal.h, qemud/qemud.h: Rename this file so it
doesn't conflict with src/internal.h.
* HACKING: Document how header files should be used.
* qemud/Makefile.am: Add src/ directory to includes.
* qemud/event.c, qemud/mdns.c, qemud/qemud.c, qemud/remote.c,
qemud/remote_protocol.c, qemud/remote_protocol.h,
qemud/remote_protocol.x, src/buf.c, src/libvirt.c,
src/nodeinfo.c, src/qemu_conf.c, src/qemu_driver.c,
src/stats_linux.c, src/storage_backend.c, src/storage_backend_fs.c,
src/storage_backend_iscsi.c, src/storage_backend_logical.c,
src/storage_conf.c, src/storage_driver.c, src/util.c,
src/util.h, src/virsh.c, src/virterror.c, src/xend_internal.c,
src/xml.c, tests/reconnect.c, tests/xmlrpctest.c,
tests/qparamtest.c: Standardize use of header files.
* docs/*, po/*: Rebuild docs.
2008-05-23 12:24:41 +04:00
# include "util.h"
2010-05-25 18:33:51 +04:00
# include "uuid.h"
2009-09-16 19:55:16 +04:00
# include "remote_driver.h"
Standardize use of header files, making internal.h primary.
* qemud/internal.h, qemud/qemud.h: Rename this file so it
doesn't conflict with src/internal.h.
* HACKING: Document how header files should be used.
* qemud/Makefile.am: Add src/ directory to includes.
* qemud/event.c, qemud/mdns.c, qemud/qemud.c, qemud/remote.c,
qemud/remote_protocol.c, qemud/remote_protocol.h,
qemud/remote_protocol.x, src/buf.c, src/libvirt.c,
src/nodeinfo.c, src/qemu_conf.c, src/qemu_driver.c,
src/stats_linux.c, src/storage_backend.c, src/storage_backend_fs.c,
src/storage_backend_iscsi.c, src/storage_backend_logical.c,
src/storage_conf.c, src/storage_driver.c, src/util.c,
src/util.h, src/virsh.c, src/virterror.c, src/xend_internal.c,
src/xml.c, tests/reconnect.c, tests/xmlrpctest.c,
tests/qparamtest.c: Standardize use of header files.
* docs/*, po/*: Rebuild docs.
2008-05-23 12:24:41 +04:00
# include "conf.h"
2008-06-06 14:52:01 +04:00
# include "memory.h"
2011-05-16 21:13:11 +04:00
# include "conf.h"
# include "virnetserver.h"
# include "threads.h"
# include "remote.h"
# include "remote_driver.h"
2010-03-26 17:53:32 +03:00
# include "hooks.h"
2011-05-16 21:13:11 +04:00
# include "uuid.h"
2010-09-15 17:44:11 +04:00
# include "virtaudit.h"
2007-02-14 04:40:09 +03:00
2008-11-21 15:16:08 +03:00
# ifdef WITH_DRIVER_MODULES
2010-03-09 21:22:22 +03:00
# include "driver.h"
2008-11-21 15:16:08 +03:00
# else
2010-03-09 21:22:22 +03:00
# ifdef WITH_QEMU
# include "qemu / qemu_driver.h"
# endif
# ifdef WITH_LXC
# include "lxc / lxc_driver.h"
# endif
2011-02-11 01:42:34 +03:00
# ifdef WITH_LIBXL
# include "libxl / libxl_driver.h"
# endif
2010-03-09 21:22:22 +03:00
# ifdef WITH_UML
# include "uml / uml_driver.h"
# endif
# ifdef WITH_NETWORK
# include "network / bridge_driver.h"
# endif
# ifdef WITH_NETCF
# include "interface / netcf_driver.h"
# endif
# ifdef WITH_STORAGE_DIR
# include "storage / storage_driver.h"
# endif
# ifdef WITH_NODE_DEVICES
# include "node_device / node_device_driver.h"
# endif
# ifdef WITH_SECRETS
# include "secret / secret_driver.h"
# endif
2010-03-25 20:46:09 +03:00
# ifdef WITH_NWFILTER
# include "nwfilter / nwfilter_driver.h"
# endif
2009-12-22 16:50:50 +03:00
# endif
2008-11-17 15:18:18 +03:00
2010-11-16 17:54:17 +03:00
# include "configmake.h"
2011-06-30 21:18:08 +04:00
# if HAVE_SASL
2011-05-16 21:13:11 +04:00
virNetSASLContextPtr saslCtxt = NULL ;
2011-06-30 21:18:08 +04:00
# endif
2011-05-16 21:13:11 +04:00
virNetServerProgramPtr remoteProgram = NULL ;
virNetServerProgramPtr qemuProgram = NULL ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
struct daemonConfig {
char * host_uuid ;
2009-02-09 20:52:38 +03:00
2011-05-16 21:13:11 +04:00
int listen_tls ;
int listen_tcp ;
char * listen_addr ;
char * tls_port ;
char * tcp_port ;
2007-12-05 18:34:05 +03:00
2011-05-16 21:13:11 +04:00
char * unix_sock_ro_perms ;
char * unix_sock_rw_perms ;
char * unix_sock_group ;
char * unix_sock_dir ;
2007-09-19 05:56:55 +04:00
2011-05-16 21:13:11 +04:00
int auth_unix_rw ;
int auth_unix_ro ;
int auth_tcp ;
int auth_tls ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
int mdns_adv ;
char * mdns_name ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
int tls_no_verify_certificate ;
char * * tls_allowed_dn_list ;
char * * sasl_allowed_username_list ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
char * key_file ;
char * cert_file ;
char * ca_file ;
char * crl_file ;
2008-12-05 01:18:44 +03:00
2011-05-16 21:13:11 +04:00
int min_workers ;
int max_workers ;
int max_clients ;
2009-01-20 22:25:15 +03:00
2011-05-16 21:13:11 +04:00
int max_requests ;
int max_client_requests ;
2010-09-15 17:44:11 +04:00
2011-05-16 21:13:11 +04:00
int log_level ;
char * log_filters ;
char * log_outputs ;
int log_buffer_size ;
2007-02-16 21:28:17 +03:00
2011-05-16 21:13:11 +04:00
int audit_level ;
int audit_logging ;
} ;
2007-03-27 14:28:45 +04:00
2009-10-16 15:14:54 +04:00
enum {
VIR_DAEMON_ERR_NONE = 0 ,
VIR_DAEMON_ERR_PIDFILE ,
VIR_DAEMON_ERR_RUNDIR ,
VIR_DAEMON_ERR_INIT ,
VIR_DAEMON_ERR_SIGNAL ,
VIR_DAEMON_ERR_PRIVS ,
VIR_DAEMON_ERR_NETWORK ,
VIR_DAEMON_ERR_CONFIG ,
2010-03-26 17:53:32 +03:00
VIR_DAEMON_ERR_HOOKS ,
2010-09-15 17:44:11 +04:00
VIR_DAEMON_ERR_AUDIT ,
2009-10-16 15:14:54 +04:00
VIR_DAEMON_ERR_LAST
} ;
VIR_ENUM_DECL ( virDaemonErr )
VIR_ENUM_IMPL ( virDaemonErr , VIR_DAEMON_ERR_LAST ,
" Initialization successful " ,
" Unable to obtain pidfile " ,
" Unable to create rundir " ,
" Unable to initialize libvirt " ,
" Unable to setup signal handlers " ,
" Unable to drop privileges " ,
" Unable to initialize network sockets " ,
2010-03-26 17:53:32 +03:00
" Unable to load configuration file " ,
2010-09-15 17:44:11 +04:00
" Unable to look for hook scripts " ,
" Unable to initialize audit system " )
2009-10-16 15:14:54 +04:00
2011-05-16 21:13:11 +04:00
static int daemonForkIntoBackground ( const char * argv0 )
2007-06-11 16:04:54 +04:00
{
2009-10-16 15:14:54 +04:00
int statuspipe [ 2 ] ;
if ( pipe ( statuspipe ) < 0 )
return - 1 ;
2007-02-14 04:40:09 +03:00
int pid = fork ( ) ;
switch ( pid ) {
case 0 :
{
int stdinfd = - 1 ;
int stdoutfd = - 1 ;
2007-02-16 21:26:18 +03:00
int nextpid ;
2007-02-14 04:40:09 +03:00
2010-11-09 23:48:48 +03:00
VIR_FORCE_CLOSE ( statuspipe [ 0 ] ) ;
2009-10-16 15:14:54 +04:00
2008-12-17 21:04:55 +03:00
if ( ( stdinfd = open ( " /dev/null " , O_RDONLY ) ) < 0 )
2007-02-14 04:40:09 +03:00
goto cleanup ;
2008-12-17 21:04:55 +03:00
if ( ( stdoutfd = open ( " /dev/null " , O_WRONLY ) ) < 0 )
2007-02-14 04:40:09 +03:00
goto cleanup ;
if ( dup2 ( stdinfd , STDIN_FILENO ) ! = STDIN_FILENO )
goto cleanup ;
if ( dup2 ( stdoutfd , STDOUT_FILENO ) ! = STDOUT_FILENO )
goto cleanup ;
if ( dup2 ( stdoutfd , STDERR_FILENO ) ! = STDERR_FILENO )
goto cleanup ;
2010-11-09 23:48:48 +03:00
if ( VIR_CLOSE ( stdinfd ) < 0 )
2007-02-14 04:40:09 +03:00
goto cleanup ;
2010-11-09 23:48:48 +03:00
if ( VIR_CLOSE ( stdoutfd ) < 0 )
2007-02-14 04:40:09 +03:00
goto cleanup ;
if ( setsid ( ) < 0 )
goto cleanup ;
nextpid = fork ( ) ;
switch ( nextpid ) {
case 0 :
2009-10-16 15:14:54 +04:00
return statuspipe [ 1 ] ;
2007-02-14 04:40:09 +03:00
case - 1 :
return - 1 ;
default :
2008-03-11 17:22:12 +03:00
_exit ( 0 ) ;
2007-02-14 04:40:09 +03:00
}
cleanup :
2010-11-09 23:48:48 +03:00
VIR_FORCE_CLOSE ( stdoutfd ) ;
VIR_FORCE_CLOSE ( stdinfd ) ;
2007-02-14 04:40:09 +03:00
return - 1 ;
}
case - 1 :
return - 1 ;
default :
{
2009-10-16 15:14:54 +04:00
int got , exitstatus = 0 ;
int ret ;
char status ;
2010-11-09 23:48:48 +03:00
VIR_FORCE_CLOSE ( statuspipe [ 1 ] ) ;
2009-10-16 15:14:54 +04:00
/* We wait to make sure the first child forked successfully */
if ( ( got = waitpid ( pid , & exitstatus , 0 ) ) < 0 | |
2007-02-14 04:40:09 +03:00
got ! = pid | |
2009-10-16 15:14:54 +04:00
exitstatus ! = 0 ) {
2007-02-14 04:40:09 +03:00
return - 1 ;
}
2009-10-16 15:14:54 +04:00
/* Now block until the second child initializes successfully */
again :
ret = read ( statuspipe [ 0 ] , & status , 1 ) ;
if ( ret = = - 1 & & errno = = EINTR )
goto again ;
if ( ret = = 1 & & status ! = 0 ) {
2010-02-24 19:29:35 +03:00
fprintf ( stderr ,
2010-05-20 23:40:54 +04:00
_ ( " %s: error: %s. Check /var/log/messages or run without "
" --daemon for more info. \n " ) , argv0 ,
2010-02-24 19:29:35 +03:00
virDaemonErrTypeToString ( status ) ) ;
2009-10-16 15:14:54 +04:00
}
_exit ( ret = = 1 & & status = = 0 ? 0 : 1 ) ;
2007-02-14 04:40:09 +03:00
}
}
}
2011-05-16 21:13:11 +04:00
static int daemonWritePidFile ( const char * pidFile , const char * argv0 )
{
2007-02-23 15:48:36 +03:00
int fd ;
FILE * fh ;
2009-02-05 19:28:03 +03:00
char ebuf [ 1024 ] ;
2007-02-23 15:48:36 +03:00
if ( pidFile [ 0 ] = = ' \0 ' )
return 0 ;
if ( ( fd = open ( pidFile , O_WRONLY | O_CREAT | O_EXCL , 0644 ) ) < 0 ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " Failed to open pid file '%s' : %s " ) ,
2009-02-05 19:28:03 +03:00
pidFile , virStrerror ( errno , ebuf , sizeof ebuf ) ) ;
2007-02-23 15:48:36 +03:00
return - 1 ;
}
2010-11-17 05:13:29 +03:00
if ( ! ( fh = VIR_FDOPEN ( fd , " w " ) ) ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " Failed to fdopen pid file '%s' : %s " ) ,
2009-02-05 19:28:03 +03:00
pidFile , virStrerror ( errno , ebuf , sizeof ebuf ) ) ;
2010-11-09 23:48:48 +03:00
VIR_FORCE_CLOSE ( fd ) ;
2007-02-23 15:48:36 +03:00
return - 1 ;
}
if ( fprintf ( fh , " %lu \n " , ( unsigned long ) getpid ( ) ) < 0 ) {
2010-05-20 23:40:54 +04:00
VIR_ERROR ( _ ( " %s: Failed to write to pid file '%s' : %s " ) ,
argv0 , pidFile , virStrerror ( errno , ebuf , sizeof ebuf ) ) ;
2010-11-17 05:13:29 +03:00
VIR_FORCE_FCLOSE ( fh ) ;
2007-02-23 15:48:36 +03:00
return - 1 ;
}
2010-11-17 05:13:29 +03:00
if ( VIR_FCLOSE ( fh ) = = EOF ) {
2010-05-20 23:40:54 +04:00
VIR_ERROR ( _ ( " %s: Failed to close pid file '%s' : %s " ) ,
argv0 , pidFile , virStrerror ( errno , ebuf , sizeof ebuf ) ) ;
2007-02-23 15:48:36 +03:00
return - 1 ;
}
return 0 ;
}
2007-06-11 16:04:54 +04:00
static int
2011-05-16 21:13:11 +04:00
daemonPidFilePath ( bool privileged ,
char * * pidfile )
2007-06-11 16:04:54 +04:00
{
2011-05-16 21:13:11 +04:00
if ( privileged ) {
if ( ! ( * pidfile = strdup ( LOCALSTATEDIR " /run/libvirtd.pid " ) ) )
goto no_memory ;
} else {
char * userdir = NULL ;
2007-09-19 05:56:55 +04:00
2011-05-16 21:13:11 +04:00
if ( ! ( userdir = virGetUserDirectory ( geteuid ( ) ) ) )
goto error ;
2007-09-19 05:56:55 +04:00
2011-07-01 03:08:41 +04:00
if ( virAsprintf ( pidfile , " %s/.libvirt/libvirtd.pid " , userdir ) < 0 ) {
VIR_FREE ( userdir ) ;
2011-05-16 21:13:11 +04:00
goto no_memory ;
2011-07-01 03:08:41 +04:00
}
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
VIR_FREE ( userdir ) ;
2007-06-11 16:04:54 +04:00
}
return 0 ;
2008-06-06 14:52:01 +04:00
2011-05-16 21:13:11 +04:00
no_memory :
virReportOOMError ( ) ;
error :
2008-06-06 14:52:01 +04:00
return - 1 ;
2007-06-11 16:04:54 +04:00
}
2011-05-16 21:13:11 +04:00
static int
daemonUnixSocketPaths ( struct daemonConfig * config ,
bool privileged ,
char * * sockfile ,
char * * rosockfile )
2009-01-22 20:49:41 +03:00
{
2011-05-16 21:13:11 +04:00
if ( config - > unix_sock_dir ) {
if ( virAsprintf ( sockfile , " %s/libvirt-sock " , config - > unix_sock_dir ) < 0 )
2010-06-03 17:36:34 +04:00
goto no_memory ;
2011-05-16 21:13:11 +04:00
if ( privileged & &
virAsprintf ( rosockfile , " %s/libvirt-sock-ro " , config - > unix_sock_dir ) < 0 )
2010-06-03 17:36:34 +04:00
goto no_memory ;
2009-10-16 14:29:01 +04:00
} else {
2011-05-16 21:13:11 +04:00
if ( privileged ) {
if ( ! ( * sockfile = strdup ( LOCALSTATEDIR " /run/libvirt/libvirt-sock " ) ) )
2010-06-03 17:36:34 +04:00
goto no_memory ;
2011-05-16 21:13:11 +04:00
if ( ! ( * rosockfile = strdup ( LOCALSTATEDIR " /run/libvirt/libvirt-sock-ro " ) ) )
2010-06-03 17:36:34 +04:00
goto no_memory ;
2011-05-16 21:13:11 +04:00
} else {
char * userdir = NULL ;
2007-02-16 21:30:55 +03:00
2011-05-16 21:13:11 +04:00
if ( ! ( userdir = virGetUserDirectory ( geteuid ( ) ) ) )
goto error ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
if ( virAsprintf ( sockfile , " @%s/.libvirt/libvirt-sock " , userdir ) < 0 ) {
VIR_FREE ( userdir ) ;
goto no_memory ;
}
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
VIR_FREE ( userdir ) ;
}
}
return 0 ;
2007-02-16 21:30:55 +03:00
2010-06-03 17:36:34 +04:00
no_memory :
2011-05-16 21:13:11 +04:00
virReportOOMError ( ) ;
error :
return - 1 ;
2007-02-14 04:40:09 +03:00
}
2011-05-16 21:13:11 +04:00
static void daemonErrorHandler ( void * opaque ATTRIBUTE_UNUSED ,
virErrorPtr err ATTRIBUTE_UNUSED )
2009-10-19 21:28:28 +04:00
{
/* Don't do anything, since logging infrastructure already
* took care of reporting the error */
}
2011-01-21 20:25:01 +03:00
static int daemonErrorLogFilter ( virErrorPtr err , int priority )
{
/* These error codes don't really reflect real errors. They
* are expected events that occur when an app tries to check
* whether a particular guest already exists . This filters
* them to a lower log level to prevent pollution of syslog
*/
switch ( err - > code ) {
case VIR_ERR_NO_DOMAIN :
case VIR_ERR_NO_NETWORK :
case VIR_ERR_NO_STORAGE_POOL :
case VIR_ERR_NO_STORAGE_VOL :
case VIR_ERR_NO_NODE_DEVICE :
case VIR_ERR_NO_INTERFACE :
case VIR_ERR_NO_NWFILTER :
case VIR_ERR_NO_SECRET :
case VIR_ERR_NO_DOMAIN_SNAPSHOT :
return VIR_LOG_DEBUG ;
}
return priority ;
}
2011-05-16 21:13:11 +04:00
static void daemonInitialize ( void )
{
2008-12-02 14:37:55 +03:00
/*
* Note that the order is important : the first ones have a higher
* priority when calling virStateInitialize . We must register
* the network , storage and nodedev drivers before any domain
* drivers , since their resources must be auto - started before
* any domains can be auto - started .
*/
2008-11-21 15:16:08 +03:00
# ifdef WITH_DRIVER_MODULES
/* We don't care if any of these fail, because the whole point
* is to allow users to only install modules they want to use .
2009-10-27 02:02:46 +03:00
* If they try to open a connection for a module that
2008-11-21 15:16:08 +03:00
* is not loaded they ' ll get a suitable error at that point
*/
virDriverLoadModule ( " network " ) ;
virDriverLoadModule ( " storage " ) ;
2008-11-21 15:27:11 +03:00
virDriverLoadModule ( " nodedev " ) ;
2009-08-14 23:48:55 +04:00
virDriverLoadModule ( " secret " ) ;
2008-12-02 14:37:55 +03:00
virDriverLoadModule ( " qemu " ) ;
virDriverLoadModule ( " lxc " ) ;
virDriverLoadModule ( " uml " ) ;
2010-03-25 20:46:09 +03:00
virDriverLoadModule ( " nwfilter " ) ;
2008-11-21 15:16:08 +03:00
# else
2010-03-09 21:22:22 +03:00
# ifdef WITH_NETWORK
2008-11-17 15:18:18 +03:00
networkRegister ( ) ;
2010-03-09 21:22:22 +03:00
# endif
# ifdef WITH_NETCF
2009-07-21 18:02:16 +04:00
interfaceRegister ( ) ;
2010-03-09 21:22:22 +03:00
# endif
# ifdef WITH_STORAGE_DIR
2008-11-17 15:18:18 +03:00
storageRegister ( ) ;
2010-03-09 21:22:22 +03:00
# endif
# if defined(WITH_NODE_DEVICES)
2008-11-21 15:27:11 +03:00
nodedevRegister ( ) ;
2010-03-09 21:22:22 +03:00
# endif
# ifdef WITH_SECRETS
2009-08-14 23:48:55 +04:00
secretRegister ( ) ;
2010-03-09 21:22:22 +03:00
# endif
2010-03-25 20:46:09 +03:00
# ifdef WITH_NWFILTER
nwfilterRegister ( ) ;
# endif
2011-02-11 01:42:34 +03:00
# ifdef WITH_LIBXL
libxlRegister ( ) ;
# endif
2010-03-09 21:22:22 +03:00
# ifdef WITH_QEMU
2008-12-02 14:37:55 +03:00
qemuRegister ( ) ;
2010-03-09 21:22:22 +03:00
# endif
# ifdef WITH_LXC
2008-12-02 14:37:55 +03:00
lxcRegister ( ) ;
2010-03-09 21:22:22 +03:00
# endif
# ifdef WITH_UML
2008-12-02 14:37:55 +03:00
umlRegister ( ) ;
2010-03-09 21:22:22 +03:00
# endif
2008-11-17 15:18:18 +03:00
# endif
2007-12-05 18:34:05 +03:00
}
2011-05-16 21:13:11 +04:00
static int daemonSetupNetworking ( virNetServerPtr srv ,
struct daemonConfig * config ,
const char * sock_path ,
const char * sock_path_ro ,
bool ipsock ,
bool privileged )
{
virNetServerServicePtr svc = NULL ;
virNetServerServicePtr svcRO = NULL ;
virNetServerServicePtr svcTCP = NULL ;
virNetServerServicePtr svcTLS = NULL ;
gid_t unix_sock_gid = 0 ;
int unix_sock_ro_mask = 0 ;
int unix_sock_rw_mask = 0 ;
if ( config - > unix_sock_group ) {
if ( virGetGroupID ( config - > unix_sock_group , & unix_sock_gid ) < 0 )
return - 1 ;
}
2007-12-05 18:34:05 +03:00
2011-05-16 21:13:11 +04:00
if ( virStrToLong_i ( config - > unix_sock_ro_perms , NULL , 8 , & unix_sock_ro_mask ) ! = 0 ) {
VIR_ERROR ( _ ( " Failed to parse mode '%s' " ) , config - > unix_sock_ro_perms ) ;
goto error ;
}
2007-12-05 18:34:05 +03:00
2011-05-16 21:13:11 +04:00
if ( virStrToLong_i ( config - > unix_sock_rw_perms , NULL , 8 , & unix_sock_rw_mask ) ! = 0 ) {
VIR_ERROR ( _ ( " Failed to parse mode '%s' " ) , config - > unix_sock_rw_perms ) ;
goto error ;
}
2007-12-05 18:34:05 +03:00
2011-05-16 21:13:11 +04:00
if ( ! ( svc = virNetServerServiceNewUNIX ( sock_path ,
unix_sock_rw_mask ,
unix_sock_gid ,
config - > auth_unix_rw ,
false ,
2011-06-30 14:45:55 +04:00
config - > max_client_requests ,
2011-05-16 21:13:11 +04:00
NULL ) ) )
goto error ;
if ( sock_path_ro & &
! ( svcRO = virNetServerServiceNewUNIX ( sock_path_ro ,
unix_sock_ro_mask ,
unix_sock_gid ,
config - > auth_unix_ro ,
true ,
2011-06-30 14:45:55 +04:00
config - > max_client_requests ,
2011-05-16 21:13:11 +04:00
NULL ) ) )
goto error ;
2009-03-02 14:13:37 +03:00
2011-05-16 21:13:11 +04:00
if ( virNetServerAddService ( srv , svc , NULL ) < 0 )
goto error ;
if ( svcRO & &
virNetServerAddService ( srv , svcRO , NULL ) < 0 )
goto error ;
2007-12-05 21:21:27 +03:00
2007-06-27 03:48:46 +04:00
if ( ipsock ) {
2011-05-16 21:13:11 +04:00
if ( config - > listen_tcp ) {
if ( ! ( svcTCP = virNetServerServiceNewTCP ( config - > listen_addr ,
config - > tcp_port ,
config - > auth_tcp ,
false ,
2011-06-30 14:45:55 +04:00
config - > max_client_requests ,
2011-05-16 21:13:11 +04:00
NULL ) ) )
goto error ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
if ( virNetServerAddService ( srv , svcTCP ,
config - > mdns_adv ? " _libvirt._tcp " : NULL ) < 0 )
goto error ;
2007-06-11 16:04:54 +04:00
}
2011-05-16 21:13:11 +04:00
if ( config - > listen_tls ) {
virNetTLSContextPtr ctxt = NULL ;
2010-09-14 20:50:25 +04:00
2011-05-16 21:13:11 +04:00
if ( config - > ca_file | |
config - > cert_file | |
config - > key_file ) {
if ( ! ( ctxt = virNetTLSContextNewServer ( config - > ca_file ,
config - > crl_file ,
config - > cert_file ,
config - > key_file ,
( const char * const * ) config - > tls_allowed_dn_list ,
config - > tls_no_verify_certificate ? false : true ) ) )
goto error ;
} else {
if ( ! ( ctxt = virNetTLSContextNewServerPath ( NULL ,
! privileged ,
( const char * const * ) config - > tls_allowed_dn_list ,
config - > tls_no_verify_certificate ? false : true ) ) )
goto error ;
2010-09-14 20:50:25 +04:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( svcTLS =
virNetServerServiceNewTCP ( config - > listen_addr ,
config - > tls_port ,
config - > auth_tls ,
false ,
2011-06-30 14:45:55 +04:00
config - > max_client_requests ,
2011-05-16 21:13:11 +04:00
ctxt ) ) ) {
virNetTLSContextFree ( ctxt ) ;
goto error ;
2010-09-14 20:50:25 +04:00
}
2011-05-16 21:13:11 +04:00
if ( virNetServerAddService ( srv , svcTLS ,
config - > mdns_adv & &
! config - > listen_tcp ? " _libvirt._tcp " : NULL ) < 0 )
goto error ;
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
2011-05-16 21:13:11 +04:00
virNetTLSContextFree ( ctxt ) ;
2007-06-11 16:04:54 +04:00
}
}
2011-06-30 21:18:08 +04:00
# if HAVE_SASL
2011-05-16 21:13:11 +04:00
if ( config - > auth_unix_rw = = REMOTE_AUTH_SASL | |
config - > auth_unix_ro = = REMOTE_AUTH_SASL | |
config - > auth_tcp = = REMOTE_AUTH_SASL | |
config - > auth_tls = = REMOTE_AUTH_SASL ) {
saslCtxt = virNetSASLContextNewServer (
( const char * const * ) config - > sasl_allowed_username_list ) ;
if ( ! saslCtxt )
2010-09-14 20:50:25 +04:00
goto error ;
2007-02-14 04:40:09 +03:00
}
2011-06-30 21:18:08 +04:00
# endif
2007-02-14 04:40:09 +03:00
2011-05-16 21:13:11 +04:00
# if HAVE_POLKIT0
if ( auth_unix_rw = = REMOTE_AUTH_POLKIT | |
auth_unix_ro = = REMOTE_AUTH_POLKIT ) {
DBusError derr ;
2009-01-20 22:25:15 +03:00
2011-05-16 21:13:11 +04:00
dbus_connection_set_change_sigpipe ( FALSE ) ;
dbus_threads_init_default ( ) ;
2009-01-20 22:25:15 +03:00
2011-05-16 21:13:11 +04:00
dbus_error_init ( & derr ) ;
server - > sysbus = dbus_bus_get ( DBUS_BUS_SYSTEM , & derr ) ;
if ( ! ( server - > sysbus ) ) {
VIR_ERROR ( _ ( " Failed to connect to system bus for PolicyKit auth: %s " ) ,
derr . message ) ;
dbus_error_free ( & derr ) ;
2010-09-14 20:50:25 +04:00
goto error ;
2008-04-04 19:09:19 +04:00
}
2011-05-16 21:13:11 +04:00
dbus_connection_set_exit_on_disconnect ( server - > sysbus , FALSE ) ;
2008-04-04 19:09:19 +04:00
}
# endif
2007-02-14 04:40:09 +03:00
return 0 ;
2007-06-11 16:04:54 +04:00
2010-09-14 20:50:25 +04:00
error :
2011-05-16 21:13:11 +04:00
virNetServerServiceFree ( svcTLS ) ;
virNetServerServiceFree ( svcTCP ) ;
virNetServerServiceFree ( svc ) ;
virNetServerServiceFree ( svcRO ) ;
2007-06-11 16:04:54 +04:00
return - 1 ;
2007-02-14 04:40:09 +03:00
}
2011-05-16 21:13:11 +04:00
static int daemonShutdownCheck ( virNetServerPtr srv ATTRIBUTE_UNUSED ,
void * opaque ATTRIBUTE_UNUSED )
2010-12-11 03:35:58 +03:00
{
2011-05-16 21:13:11 +04:00
if ( virStateActive ( ) )
return 0 ;
2009-01-15 22:56:05 +03:00
2011-05-16 21:13:11 +04:00
return 1 ;
2007-02-14 04:40:09 +03:00
}
2011-05-16 21:13:11 +04:00
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
/* Allocate an array of malloc'd strings from the config file, filename
* ( used only in diagnostics ) , using handle " conf " . Upon error , return - 1
* and free any allocated memory . Otherwise , save the array in * list_arg
* and return 0.
*/
static int
remoteConfigGetStringList ( virConfPtr conf , const char * key , char * * * list_arg ,
const char * filename )
{
char * * list ;
virConfValuePtr p = virConfGetValue ( conf , key ) ;
if ( ! p )
return 0 ;
switch ( p - > type ) {
case VIR_CONF_STRING :
2008-06-06 14:52:01 +04:00
if ( VIR_ALLOC_N ( list , 2 ) < 0 ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " failed to allocate memory for %s config list " ) , key ) ;
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
return - 1 ;
}
list [ 0 ] = strdup ( p - > str ) ;
list [ 1 ] = NULL ;
if ( list [ 0 ] = = NULL ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " failed to allocate memory for %s config list value " ) ,
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
key ) ;
2008-06-06 14:52:01 +04:00
VIR_FREE ( list ) ;
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
return - 1 ;
}
break ;
case VIR_CONF_LIST : {
int i , len = 0 ;
virConfValuePtr pp ;
for ( pp = p - > list ; pp ; pp = pp - > next )
len + + ;
2008-06-06 14:52:01 +04:00
if ( VIR_ALLOC_N ( list , 1 + len ) < 0 ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " failed to allocate memory for %s config list " ) , key ) ;
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
return - 1 ;
}
for ( i = 0 , pp = p - > list ; pp ; + + i , pp = pp - > next ) {
if ( pp - > type ! = VIR_CONF_STRING ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " remoteReadConfigFile: %s: %s: "
2010-04-02 23:44:04 +04:00
" must be a string or list of strings " ) ,
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
filename , key ) ;
2008-06-06 14:52:01 +04:00
VIR_FREE ( list ) ;
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
return - 1 ;
}
list [ i ] = strdup ( pp - > str ) ;
if ( list [ i ] = = NULL ) {
int j ;
for ( j = 0 ; j < i ; j + + )
2008-06-06 14:52:01 +04:00
VIR_FREE ( list [ j ] ) ;
VIR_FREE ( list ) ;
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " failed to allocate memory for %s config list value " ) ,
key ) ;
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
return - 1 ;
}
}
list [ i ] = NULL ;
break ;
}
default :
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " remoteReadConfigFile: %s: %s: "
2010-04-02 23:44:04 +04:00
" must be a string or list of strings " ) ,
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
filename , key ) ;
return - 1 ;
}
* list_arg = list ;
return 0 ;
}
/* A helper function used by each of the following macros. */
static int
checkType ( virConfValuePtr p , const char * filename ,
const char * key , virConfType required_type )
{
if ( p - > type ! = required_type ) {
2009-01-06 21:32:03 +03:00
VIR_ERROR ( _ ( " remoteReadConfigFile: %s: %s: invalid type: "
2010-04-02 23:44:04 +04:00
" got %s; expected %s " ) , filename , key ,
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
virConfTypeName ( p - > type ) ,
virConfTypeName ( required_type ) ) ;
return - 1 ;
}
return 0 ;
}
/* If there is no config data for the key, #var_name, then do nothing.
If there is valid data of type VIR_CONF_STRING , and strdup succeeds ,
store the result in var_name . Otherwise , ( i . e . invalid type , or strdup
failure ) , give a diagnostic and " goto " the cleanup - and - fail label . */
# define GET_CONF_STR(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue ( conf , # var_name ) ; \
if ( p ) { \
if ( checkType ( p , filename , # var_name , VIR_CONF_STRING ) < 0 ) \
2011-05-16 21:13:11 +04:00
goto error ; \
VIR_FREE ( data - > var_name ) ; \
if ( ! ( data - > var_name = strdup ( p - > str ) ) ) { \
virReportOOMError ( ) ; \
goto error ; \
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
} \
} \
} while ( 0 )
/* Like GET_CONF_STR, but for integral values. */
# define GET_CONF_INT(conf, filename, var_name) \
do { \
virConfValuePtr p = virConfGetValue ( conf , # var_name ) ; \
if ( p ) { \
if ( checkType ( p , filename , # var_name , VIR_CONF_LONG ) < 0 ) \
2011-05-16 21:13:11 +04:00
goto error ; \
data - > var_name = p - > l ; \
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
} \
} while ( 0 )
2007-12-05 18:34:05 +03:00
static int remoteConfigGetAuth ( virConfPtr conf , const char * key , int * auth , const char * filename ) {
virConfValuePtr p ;
p = virConfGetValue ( conf , key ) ;
if ( ! p )
return 0 ;
2007-12-12 00:20:13 +03:00
if ( checkType ( p , filename , key , VIR_CONF_STRING ) < 0 )
2007-12-05 18:34:05 +03:00
return - 1 ;
if ( ! p - > str )
return 0 ;
if ( STREQ ( p - > str , " none " ) ) {
2011-05-16 21:13:11 +04:00
* auth = VIR_NET_SERVER_SERVICE_AUTH_NONE ;
2011-06-30 21:18:08 +04:00
# if HAVE_SASL
2007-12-05 18:34:05 +03:00
} else if ( STREQ ( p - > str , " sasl " ) ) {
2011-05-16 21:13:11 +04:00
* auth = VIR_NET_SERVER_SERVICE_AUTH_SASL ;
2011-06-30 21:18:08 +04:00
# endif
2007-12-05 21:21:27 +03:00
} else if ( STREQ ( p - > str , " polkit " ) ) {
2011-05-16 21:13:11 +04:00
* auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT ;
2007-12-05 18:34:05 +03:00
} else {
2010-01-19 16:17:20 +03:00
VIR_ERROR ( _ ( " remoteReadConfigFile: %s: %s: unsupported auth %s " ) ,
Mark all qemudLog diagnostics for translation.
* po/POTFILES.in: Add names of many new files.
* Makefile.maint (err_func_re): Add qemudLog.
Mark diagnostics with _(...). Split some long lines.
* qemud/qemud.c (remoteCheckCertFile, remoteInitializeGnuTLS):
(qemudDispatchSignalEvent, qemudSetCloseExec, qemudSetNonBlock):
(qemudWritePidFile, qemudListenUnix, remoteMakeSockets):
(remoteListenTCP, qemudInitPaths, qemudInitialize):
(qemudNetworkInit, remoteInitializeTLSSession, remoteCheckDN):
(remoteCheckCertificate, remoteCheckAccess, qemudDispatchServer):
(qemudClientReadBuf, qemudDispatchClientRead):
(qemudClientWriteBuf, qemudDispatchClientWrite, qemudOneLoop):
(remoteConfigGetStringList, checkType, GET_CONF_STR):
(remoteConfigGetAuth, remoteReadConfigFile, main):
* qemud/remote.c (remoteDispatchAuthSaslInit, remoteSASLCheckSSF):
(remoteSASLCheckAccess, remoteDispatchAuthSaslStart):
(remoteDispatchAuthSaslStep, remoteDispatchAuthSaslInit):
(remoteDispatchAuthSaslStart, remoteDispatchAuthSaslStep):
(qemudGetSocketIdentity, remoteDispatchAuthPolkit):
* src/iptables.c (notifyRulesUpdated, MAX_FILE_LEN, iptRulesSave):
(iptRulesReload):
* src/qemu_conf.c (qemudExtractVersionInfo, qemudLoadConfig):
(qemudLoadNetworkConfig, qemudScanConfigDir):
* src/qemu_driver.c (qemudSetCloseExec, qemudSetNonBlock):
(qemudAutostartConfigs, qemudStartup, qemudReload):
(qemudWaitForMonitor, qemudStartVMDaemon, qemudVMData):
(qemudShutdownVMDaemon, qemudStartNetworkDaemon):
(qemudShutdownNetworkDaemon, qemudMonitorCommand):
(qemudDomainUndefine, qemudNetworkUndefine):
* src/uuid.c (virUUIDGenerate):
* src/xm_internal.c (xenXMAttachInterface):
2008-02-07 19:50:17 +03:00
filename , key , p - > str ) ;
2007-12-05 18:34:05 +03:00
return - 1 ;
}
return 0 ;
}
2008-12-22 15:53:26 +03:00
/*
* Set up the logging environment
2011-03-03 09:48:06 +03:00
* By default if daemonized all errors go to the logfile libvirtd . log ,
* but if verbose or error debugging is asked for then also output
2011-03-08 13:31:20 +03:00
* informational and debug messages . Default size if 64 kB .
2008-12-22 15:53:26 +03:00
*/
2008-12-22 19:16:10 +03:00
static int
2011-05-16 21:13:11 +04:00
daemonSetupLogging ( struct daemonConfig * config ,
bool privileged ,
bool verbose ,
bool godaemon )
2009-10-23 10:56:21 +04:00
{
2008-12-22 15:53:26 +03:00
virLogReset ( ) ;
2008-12-22 19:16:10 +03:00
/*
2009-08-06 17:55:07 +04:00
* Libvirtd ' s order of precedence is :
* cmdline > environment > config
*
* In order to achieve this , we must process configuration in
* different order for the log level versus the filters and
* outputs . Because filters and outputs append , we have to look at
* the environment first and then only check the config file if
* there was no result from the environment . The default output is
* then applied only if there was no setting from either of the
* first two . Because we don ' t have a way to determine if the log
* level has been set , we must process variables in the opposite
* order , each one overriding the previous .
2008-12-22 19:16:10 +03:00
*/
2011-05-16 21:13:11 +04:00
if ( config - > log_level ! = 0 )
virLogSetDefaultPriority ( config - > log_level ) ;
2009-08-06 17:45:50 +04:00
2009-08-06 17:55:07 +04:00
virLogSetFromEnv ( ) ;
2009-08-06 17:45:50 +04:00
2011-05-16 21:13:11 +04:00
virLogSetBufferSize ( config - > log_buffer_size ) ;
2008-12-22 15:53:26 +03:00
2011-05-16 21:13:11 +04:00
if ( virLogGetNbFilters ( ) = = 0 )
virLogParseFilters ( config - > log_filters ) ;
if ( virLogGetNbOutputs ( ) = = 0 )
virLogParseOutputs ( config - > log_outputs ) ;
2008-12-22 15:53:26 +03:00
/*
2011-03-03 09:48:06 +03:00
* If no defined outputs , then direct to libvirtd . log when running
2009-08-06 17:45:50 +04:00
* as daemon . Otherwise the default output is stderr .
2008-12-22 15:53:26 +03:00
*/
2009-08-06 17:45:50 +04:00
if ( virLogGetNbOutputs ( ) = = 0 ) {
2009-07-01 15:21:15 +04:00
char * tmp = NULL ;
2011-03-03 09:48:06 +03:00
2009-01-21 00:50:31 +03:00
if ( godaemon ) {
2011-05-16 21:13:11 +04:00
if ( privileged ) {
2011-03-03 09:48:06 +03:00
if ( virAsprintf ( & tmp , " %d:file:%s/log/libvirt/libvirtd.log " ,
virLogGetDefaultPriority ( ) ,
LOCALSTATEDIR ) = = - 1 )
2011-05-16 21:13:11 +04:00
goto no_memory ;
2011-03-03 09:48:06 +03:00
} else {
char * userdir = virGetUserDirectory ( geteuid ( ) ) ;
if ( ! userdir )
2011-05-16 21:13:11 +04:00
goto error ;
2011-03-03 09:48:06 +03:00
if ( virAsprintf ( & tmp , " %d:file:%s/.libvirt/libvirtd.log " ,
2011-06-03 01:56:32 +04:00
virLogGetDefaultPriority ( ) , userdir ) = = - 1 ) {
VIR_FREE ( userdir ) ;
2011-05-16 21:13:11 +04:00
goto no_memory ;
2011-06-03 01:56:32 +04:00
}
2011-06-07 01:03:26 +04:00
VIR_FREE ( userdir ) ;
2011-03-03 09:48:06 +03:00
}
2009-01-21 00:50:31 +03:00
} else {
2011-03-03 09:48:06 +03:00
if ( virAsprintf ( & tmp , " %d:stderr " , virLogGetDefaultPriority ( ) ) < 0 )
2011-05-16 21:13:11 +04:00
goto no_memory ;
2009-01-21 00:50:31 +03:00
}
2009-07-01 15:21:15 +04:00
virLogParseOutputs ( tmp ) ;
VIR_FREE ( tmp ) ;
2009-06-03 14:36:17 +04:00
}
2009-08-06 17:55:07 +04:00
/*
* Command line override for - - verbose
*/
if ( ( verbose ) & & ( virLogGetDefaultPriority ( ) > VIR_LOG_INFO ) )
virLogSetDefaultPriority ( VIR_LOG_INFO ) ;
2011-05-16 21:13:11 +04:00
return 0 ;
no_memory :
virReportOOMError ( ) ;
error :
return - 1 ;
}
2008-12-22 19:16:10 +03:00
2011-05-16 21:13:11 +04:00
static int
daemonConfigFilePath ( bool privileged , char * * configfile )
{
if ( privileged ) {
if ( ! ( * configfile = strdup ( SYSCONFDIR " /libvirt/libvirtd.conf " ) ) )
goto no_memory ;
} else {
char * userdir = NULL ;
if ( ! ( userdir = virGetUserDirectory ( geteuid ( ) ) ) )
goto error ;
if ( virAsprintf ( configfile , " %s/.libvirt/libvirtd.conf " , userdir ) < 0 ) {
VIR_FREE ( userdir ) ;
goto no_memory ;
}
VIR_FREE ( userdir ) ;
}
return 0 ;
2011-03-03 09:48:06 +03:00
2011-05-16 21:13:11 +04:00
no_memory :
2011-03-03 09:48:06 +03:00
virReportOOMError ( ) ;
2011-05-16 21:13:11 +04:00
error :
return - 1 ;
2011-03-03 09:48:06 +03:00
}
static void
2011-05-16 21:13:11 +04:00
daemonConfigFree ( struct daemonConfig * data ) ;
static struct daemonConfig *
2011-06-28 23:09:05 +04:00
daemonConfigNew ( bool privileged ATTRIBUTE_UNUSED )
2011-03-03 09:48:06 +03:00
{
2011-05-16 21:13:11 +04:00
struct daemonConfig * data ;
char * localhost ;
int ret ;
if ( VIR_ALLOC ( data ) < 0 ) {
virReportOOMError ( ) ;
return NULL ;
}
data - > listen_tls = 1 ;
data - > listen_tcp = 0 ;
if ( ! ( data - > tls_port = strdup ( LIBVIRTD_TLS_PORT ) ) )
goto no_memory ;
if ( ! ( data - > tcp_port = strdup ( LIBVIRTD_TCP_PORT ) ) )
goto no_memory ;
/* Only default to PolicyKit if running as root */
# if HAVE_POLKIT
if ( privileged ) {
data - > auth_unix_rw = REMOTE_AUTH_POLKIT ;
data - > auth_unix_ro = REMOTE_AUTH_POLKIT ;
} else {
# endif
data - > auth_unix_rw = REMOTE_AUTH_NONE ;
data - > auth_unix_ro = REMOTE_AUTH_NONE ;
# if HAVE_POLKIT
}
# endif
if ( data - > auth_unix_rw = = REMOTE_AUTH_POLKIT )
data - > unix_sock_rw_perms = strdup ( " 0777 " ) ; /* Allow world */
else
data - > unix_sock_rw_perms = strdup ( " 0700 " ) ; /* Allow user only */
data - > unix_sock_ro_perms = strdup ( " 0777 " ) ; /* Always allow world */
if ( ! data - > unix_sock_ro_perms | |
! data - > unix_sock_rw_perms )
goto no_memory ;
# if HAVE_SASL
data - > auth_tcp = REMOTE_AUTH_SASL ;
# else
data - > auth_tcp = REMOTE_AUTH_NONE ;
# endif
data - > auth_tls = REMOTE_AUTH_NONE ;
data - > mdns_adv = 1 ;
data - > min_workers = 5 ;
data - > max_workers = 20 ;
data - > max_clients = 20 ;
data - > max_requests = 20 ;
data - > max_client_requests = 5 ;
data - > log_buffer_size = 64 ;
data - > audit_level = 1 ;
data - > audit_logging = 0 ;
localhost = virGetHostname ( NULL ) ;
if ( localhost = = NULL ) {
/* we couldn't resolve the hostname; assume that we are
* running in disconnected operation , and report a less
* useful Avahi string
*/
ret = virAsprintf ( & data - > mdns_name , " Virtualization Host " ) ;
} else {
char * tmp ;
/* Extract the host part of the potentially FQDN */
if ( ( tmp = strchr ( localhost , ' . ' ) ) )
* tmp = ' \0 ' ;
ret = virAsprintf ( & data - > mdns_name , " Virtualization Host %s " ,
localhost ) ;
}
VIR_FREE ( localhost ) ;
if ( ret < 0 )
goto no_memory ;
return data ;
no_memory :
virReportOOMError ( ) ;
daemonConfigFree ( data ) ;
return NULL ;
}
static void
daemonConfigFree ( struct daemonConfig * data )
{
char * * tmp ;
if ( ! data )
return ;
VIR_FREE ( data - > listen_addr ) ;
VIR_FREE ( data - > tls_port ) ;
VIR_FREE ( data - > tcp_port ) ;
VIR_FREE ( data - > unix_sock_ro_perms ) ;
VIR_FREE ( data - > unix_sock_rw_perms ) ;
VIR_FREE ( data - > unix_sock_group ) ;
VIR_FREE ( data - > unix_sock_dir ) ;
VIR_FREE ( data - > mdns_name ) ;
tmp = data - > tls_allowed_dn_list ;
while ( tmp & & * tmp ) {
VIR_FREE ( * tmp ) ;
tmp + + ;
}
VIR_FREE ( data - > tls_allowed_dn_list ) ;
tmp = data - > sasl_allowed_username_list ;
while ( tmp & & * tmp ) {
VIR_FREE ( * tmp ) ;
tmp + + ;
}
VIR_FREE ( data - > sasl_allowed_username_list ) ;
VIR_FREE ( data - > key_file ) ;
VIR_FREE ( data - > ca_file ) ;
VIR_FREE ( data - > cert_file ) ;
VIR_FREE ( data - > crl_file ) ;
VIR_FREE ( data - > log_filters ) ;
VIR_FREE ( data - > log_outputs ) ;
VIR_FREE ( data ) ;
2008-12-22 15:53:26 +03:00
}
2007-12-05 22:25:44 +03:00
2011-05-16 21:13:11 +04:00
2007-06-11 16:04:54 +04:00
/* Read the config file if it exists.
* Only used in the remote case , hence the name .
*/
static int
2011-05-16 21:13:11 +04:00
daemonConfigLoad ( struct daemonConfig * data ,
const char * filename )
2007-06-11 16:04:54 +04:00
{
virConfPtr conf ;
2009-06-19 16:34:30 +04:00
conf = virConfReadFile ( filename , 0 ) ;
2011-05-16 21:13:11 +04:00
if ( ! conf )
return - 1 ;
2008-12-22 15:53:26 +03:00
2007-12-05 21:56:27 +03:00
GET_CONF_INT ( conf , filename , listen_tcp ) ;
GET_CONF_INT ( conf , filename , listen_tls ) ;
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
GET_CONF_STR ( conf , filename , tls_port ) ;
GET_CONF_STR ( conf , filename , tcp_port ) ;
2008-05-15 00:57:20 +04:00
GET_CONF_STR ( conf , filename , listen_addr ) ;
2008-05-15 01:22:04 +04:00
2011-05-16 21:13:11 +04:00
if ( remoteConfigGetAuth ( conf , " auth_unix_rw " , & data - > auth_unix_rw , filename ) < 0 )
goto error ;
2007-12-05 21:21:27 +03:00
# if HAVE_POLKIT
/* Change default perms to be wide-open if PolicyKit is enabled.
* Admin can always override in config file
*/
2011-05-16 21:13:11 +04:00
if ( data - > auth_unix_rw = = REMOTE_AUTH_POLKIT ) {
VIR_FREE ( data - > unix_sock_rw_perms ) ;
2011-06-28 23:09:05 +04:00
if ( ! ( data - > unix_sock_rw_perms = strdup ( " 0777 " ) ) ) {
virReportOOMError ( ) ;
goto error ;
}
2011-05-16 21:13:11 +04:00
}
2007-12-05 21:21:27 +03:00
# endif
2011-05-16 21:13:11 +04:00
if ( remoteConfigGetAuth ( conf , " auth_unix_ro " , & data - > auth_unix_ro , filename ) < 0 )
goto error ;
if ( remoteConfigGetAuth ( conf , " auth_tcp " , & data - > auth_tcp , filename ) < 0 )
goto error ;
if ( remoteConfigGetAuth ( conf , " auth_tls " , & data - > auth_tls , filename ) < 0 )
goto error ;
2007-12-05 18:34:05 +03:00
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
GET_CONF_STR ( conf , filename , unix_sock_group ) ;
GET_CONF_STR ( conf , filename , unix_sock_ro_perms ) ;
GET_CONF_STR ( conf , filename , unix_sock_rw_perms ) ;
2007-09-19 06:28:01 +04:00
2009-02-09 20:52:38 +03:00
GET_CONF_STR ( conf , filename , unix_sock_dir ) ;
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
GET_CONF_INT ( conf , filename , mdns_adv ) ;
GET_CONF_STR ( conf , filename , mdns_name ) ;
2007-09-19 05:56:55 +04:00
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
GET_CONF_INT ( conf , filename , tls_no_verify_certificate ) ;
2007-06-11 16:04:54 +04:00
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
GET_CONF_STR ( conf , filename , key_file ) ;
GET_CONF_STR ( conf , filename , cert_file ) ;
GET_CONF_STR ( conf , filename , ca_file ) ;
GET_CONF_STR ( conf , filename , crl_file ) ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
if ( remoteConfigGetStringList ( conf , " tls_allowed_dn_list " ,
& data - > tls_allowed_dn_list , filename ) < 0 )
goto error ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
if ( remoteConfigGetStringList ( conf , " sasl_allowed_username_list " ,
& data - > sasl_allowed_username_list , filename ) < 0 )
goto error ;
2007-06-11 16:04:54 +04:00
2008-12-05 01:18:44 +03:00
GET_CONF_INT ( conf , filename , min_workers ) ;
GET_CONF_INT ( conf , filename , max_workers ) ;
GET_CONF_INT ( conf , filename , max_clients ) ;
2009-01-20 22:25:15 +03:00
GET_CONF_INT ( conf , filename , max_requests ) ;
GET_CONF_INT ( conf , filename , max_client_requests ) ;
2010-09-15 17:44:11 +04:00
GET_CONF_INT ( conf , filename , audit_level ) ;
GET_CONF_INT ( conf , filename , audit_logging ) ;
2010-05-25 18:33:51 +04:00
GET_CONF_STR ( conf , filename , host_uuid ) ;
2011-05-16 21:13:11 +04:00
GET_CONF_INT ( conf , filename , log_level ) ;
GET_CONF_STR ( conf , filename , log_filters ) ;
GET_CONF_STR ( conf , filename , log_outputs ) ;
GET_CONF_INT ( conf , filename , log_buffer_size ) ;
2010-05-25 18:33:51 +04:00
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
virConfFree ( conf ) ;
return 0 ;
2007-06-11 16:04:54 +04:00
2011-05-16 21:13:11 +04:00
error :
Detect heap allocation failure; factor out some duplication.
* qemud/qemud.c (tls_port, tcp_port, mdns_name, tls_allowed_ip_list):
(tls_allowed_dn_list): Remove "const", now that we free these.
(unix_sock_rw_mask): Rename from unix_sock_rw_perms, so that
the latter name can be used as a local string variable, so that the
variable name matches the config attribute name.
(unix_sock_ro_mask): Rename from unix_sock_ro_perms, likewise.
(remoteCheckDN, remoteCheckAccess): Adapt to const removal.
(qemudDispatchServer): Check for heap allocation failure.
(remoteConfigGetStringList): New function, based on code from Dan Berrangé.
(CHECK_TYPE): Remove macro.
(checkType): New function.
(GET_CONF_INT, GET_CONF_STR): New macros.
(remoteReadConfigFile): Use new macros to avoid duplication and to
check for allocation failure.
* src/conf.h (virConfTypeName): New static inline function.
2007-11-30 18:43:42 +03:00
virConfFree ( conf ) ;
return - 1 ;
2007-06-11 16:04:54 +04:00
}
2008-12-12 10:56:50 +03:00
/* Display version information. */
static void
2011-05-16 21:13:11 +04:00
daemonVersion ( const char * argv0 )
2008-12-12 10:56:50 +03:00
{
printf ( " %s (%s) %s \n " , argv0 , PACKAGE_NAME , PACKAGE_VERSION ) ;
}
2009-01-22 20:49:41 +03:00
# ifdef __sun
static int
2011-05-16 21:13:11 +04:00
daemonSetupPrivs ( void )
2009-01-22 20:49:41 +03:00
{
chown ( " /var/run/libvirt " , SYSTEM_UID , SYSTEM_UID ) ;
if ( __init_daemon_priv ( PU_RESETGROUPS | PU_CLEARLIMITSET ,
SYSTEM_UID , SYSTEM_UID , PRIV_XVM_CONTROL , NULL ) ) {
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " additional privileges are required " ) ) ;
2009-01-22 20:49:41 +03:00
return - 1 ;
}
if ( priv_set ( PRIV_OFF , PRIV_ALLSETS , PRIV_FILE_LINK_ANY , PRIV_PROC_INFO ,
PRIV_PROC_SESSION , PRIV_PROC_EXEC , PRIV_PROC_FORK , NULL ) ) {
2011-05-09 13:24:09 +04:00
VIR_ERROR ( _ ( " failed to set reduced privileges " ) ) ;
2009-01-22 20:49:41 +03:00
return - 1 ;
}
return 0 ;
}
# else
2011-05-16 21:13:11 +04:00
# define daemonSetupPrivs() 0
2009-01-22 20:49:41 +03:00
# endif
2009-10-16 14:48:50 +04:00
2011-05-16 21:13:11 +04:00
static void daemonShutdownHandler ( virNetServerPtr srv ,
siginfo_t * sig ATTRIBUTE_UNUSED ,
void * opaque ATTRIBUTE_UNUSED )
2009-10-16 14:48:50 +04:00
{
2011-05-16 21:13:11 +04:00
virNetServerQuit ( srv ) ;
}
2009-10-16 14:48:50 +04:00
2011-05-16 21:13:11 +04:00
static int daemonSetupSignals ( virNetServerPtr srv )
{
if ( virNetServerAddSignalHandler ( srv , SIGINT , daemonShutdownHandler , NULL ) < 0 )
2009-10-16 14:48:50 +04:00
return - 1 ;
2011-05-16 21:13:11 +04:00
if ( virNetServerAddSignalHandler ( srv , SIGQUIT , daemonShutdownHandler , NULL ) < 0 )
return - 1 ;
if ( virNetServerAddSignalHandler ( srv , SIGTERM , daemonShutdownHandler , NULL ) < 0 )
return - 1 ;
return 0 ;
}
2009-10-16 14:48:50 +04:00
2011-05-16 21:13:11 +04:00
static void daemonRunStateInit ( void * opaque )
{
virNetServerPtr srv = opaque ;
2009-10-16 14:48:50 +04:00
2011-05-16 21:13:11 +04:00
/* Start the stateful HV drivers
* This is delibrately done after telling the parent process
* we ' re ready , since it can take a long time and this will
* seriously delay OS bootup process */
if ( virStateInitialize ( virNetServerIsPrivileged ( srv ) ) < 0 ) {
VIR_ERROR ( _ ( " Driver state initialization failed " ) ) ;
virNetServerFree ( srv ) ;
return ;
2009-10-16 14:48:50 +04:00
}
2011-05-16 21:13:11 +04:00
/* Only now accept clients from network */
virNetServerUpdateServices ( srv , true ) ;
virNetServerFree ( srv ) ;
}
2009-10-16 14:48:50 +04:00
2011-05-16 21:13:11 +04:00
static int daemonStateInit ( virNetServerPtr srv )
{
virThread thr ;
virNetServerRef ( srv ) ;
if ( virThreadCreate ( & thr , false , daemonRunStateInit , srv ) < 0 ) {
virNetServerFree ( srv ) ;
return - 1 ;
}
2009-10-16 14:48:50 +04:00
return 0 ;
}
2007-04-04 13:32:00 +04:00
/* Print command-line usage. */
static void
2011-05-16 21:13:11 +04:00
daemonUsage ( const char * argv0 , bool privileged )
2007-04-04 13:32:00 +04:00
{
fprintf ( stderr ,
2010-05-20 12:01:32 +04:00
_ ( " \n \
2007-06-11 16:04:54 +04:00
Usage : \ n \
% s [ options ] \ n \
\ n \
Options : \ n \
- v | - - verbose Verbose messages . \ n \
- d | - - daemon Run as a daemon & write PID file . \ n \
2007-06-27 03:48:46 +04:00
- l | - - listen Listen for TCP / IP connections . \ n \
- t | - - timeout < secs > Exit after timeout period . \ n \
2007-08-07 17:24:22 +04:00
- f | - - config < file > Configuration file . \ n \
2008-12-12 10:56:50 +03:00
| - - version Display version information . \ n \
2007-06-11 16:04:54 +04:00
- p | - - pid - file < file > Change name of PID file . \ n \
\ n \
2011-05-16 21:13:11 +04:00
libvirt management daemon : \ n " ), argv0);
if ( privileged ) {
fprintf ( stderr ,
_ ( " \n \
2007-06-11 16:04:54 +04:00
Default paths : \ n \
\ n \
2009-11-10 17:53:20 +03:00
Configuration file ( unless overridden by - f ) : \ n \
2010-05-20 12:01:32 +04:00
% s / libvirt / libvirtd . conf \ n \
2007-06-11 16:04:54 +04:00
\ n \
2011-05-16 21:13:11 +04:00
Sockets : \ n \
2010-05-20 12:01:32 +04:00
% s / run / libvirt / libvirt - sock \ n \
% s / run / libvirt / libvirt - sock - ro \ n \
2007-06-27 03:48:46 +04:00
\ n \
2011-05-16 21:13:11 +04:00
TLS : \ n \
CA certificate : % s / pki / CA / caert . pem \ n \
Server certificate : % s / pki / libvirt / servercert . pem \ n \
Server private key : % s / pki / libvirt / private / serverkey . pem \ n \
\ n \
PID file ( unless overridden by - p ) : \ n \
% s / run / libvirtd . pid \ n \
\ n " ),
SYSCONFDIR ,
LOCALSTATEDIR ,
LOCALSTATEDIR ,
SYSCONFDIR ,
SYSCONFDIR ,
SYSCONFDIR ,
LOCALSTATEDIR ) ;
} else {
fprintf ( stderr ,
" %s " , _ ( " \n \
Default paths : \ n \
\ n \
Configuration file ( unless overridden by - f ) : \ n \
$ HOME / . libvirt / libvirtd . conf \ n \
\ n \
Sockets : \ n \
2007-06-27 03:48:46 +04:00
$ HOME / . libvirt / libvirt - sock ( in UNIX abstract namespace ) \ n \
2007-06-11 16:04:54 +04:00
\ n \
TLS : \ n \
2011-05-16 21:13:11 +04:00
CA certificate : $ HOME / . pki / libvirt / cacert . pem \ n \
Server certificate : $ HOME / . pki / libvirt / servercert . pem \ n \
Server private key : $ HOME / . pki / libvirt / serverkey . pem \ n \
2007-06-11 16:04:54 +04:00
\ n \
2011-05-16 21:13:11 +04:00
PID file : \ n \
$ HOME / . libvirt / libvirtd . pid \ n \
\ n " ));
}
2007-04-04 13:32:00 +04:00
}
2008-12-12 10:56:50 +03:00
enum {
OPT_VERSION = 129
} ;
2007-02-14 04:40:09 +03:00
# define MAX_LISTEN 5
int main ( int argc , char * * argv ) {
2011-05-16 21:13:11 +04:00
virNetServerPtr srv = NULL ;
char * remote_config_file = NULL ;
2009-10-16 15:14:54 +04:00
int statuswrite = - 1 ;
2007-02-23 15:48:36 +03:00
int ret = 1 ;
2011-05-16 21:13:11 +04:00
char * pid_file = NULL ;
char * sock_file = NULL ;
char * sock_file_ro = NULL ;
int timeout = - 1 ; /* -t: Shutdown timeout */
int verbose = 0 ;
int godaemon = 0 ;
int ipsock = 0 ;
struct daemonConfig * config ;
bool privileged = geteuid ( ) = = 0 ? true : false ;
2007-02-14 04:40:09 +03:00
struct option opts [ ] = {
{ " verbose " , no_argument , & verbose , 1 } ,
{ " daemon " , no_argument , & godaemon , 1 } ,
2007-06-27 03:48:46 +04:00
{ " listen " , no_argument , & ipsock , 1 } ,
2007-08-07 17:24:22 +04:00
{ " config " , required_argument , NULL , ' f ' } ,
2007-04-04 13:32:00 +04:00
{ " timeout " , required_argument , NULL , ' t ' } ,
{ " pid-file " , required_argument , NULL , ' p ' } ,
2008-12-12 10:56:50 +03:00
{ " version " , no_argument , NULL , OPT_VERSION } ,
2007-04-04 13:32:00 +04:00
{ " help " , no_argument , NULL , ' ? ' } ,
2007-02-14 04:40:09 +03:00
{ 0 , 0 , 0 , 0 }
} ;
2010-11-16 22:01:37 +03:00
if ( setlocale ( LC_ALL , " " ) = = NULL | |
bindtextdomain ( PACKAGE , LOCALEDIR ) = = NULL | |
textdomain ( PACKAGE ) = = NULL | |
virInitialize ( ) < 0 ) {
2011-05-16 21:13:11 +04:00
fprintf ( stderr , _ ( " %s: initialization failed \n " ) , argv [ 0 ] ) ;
2010-11-16 22:01:37 +03:00
exit ( EXIT_FAILURE ) ;
2010-05-20 11:52:20 +04:00
}
2009-10-16 14:29:01 +04:00
2007-02-14 04:40:09 +03:00
while ( 1 ) {
int optidx = 0 ;
int c ;
char * tmp ;
2007-08-07 17:24:22 +04:00
c = getopt_long ( argc , argv , " ldf:p:t:v " , opts , & optidx ) ;
2007-02-14 04:40:09 +03:00
if ( c = = - 1 ) {
break ;
}
switch ( c ) {
case 0 :
/* Got one of the flags */
break ;
case ' v ' :
verbose = 1 ;
break ;
case ' d ' :
godaemon = 1 ;
break ;
2007-06-27 03:48:46 +04:00
case ' l ' :
ipsock = 1 ;
2007-02-14 04:40:09 +03:00
break ;
case ' t ' :
2008-02-08 12:15:16 +03:00
if ( virStrToLong_i ( optarg , & tmp , 10 , & timeout ) ! = 0
2007-11-14 13:53:05 +03:00
| | timeout < = 0
/* Ensure that we can multiply by 1000 without overflowing. */
| | timeout > INT_MAX / 1000 )
2007-02-14 04:40:09 +03:00
timeout = - 1 ;
break ;
2007-02-23 15:48:36 +03:00
case ' p ' :
2011-05-16 21:13:11 +04:00
VIR_FREE ( pid_file ) ;
if ( ! ( pid_file = strdup ( optarg ) ) )
exit ( EXIT_FAILURE ) ;
2007-06-11 16:04:54 +04:00
break ;
case ' f ' :
2011-05-16 21:13:11 +04:00
VIR_FREE ( remote_config_file ) ;
if ( ! ( remote_config_file = strdup ( optarg ) ) )
exit ( EXIT_FAILURE ) ;
2007-02-23 15:48:36 +03:00
break ;
2008-12-12 10:56:50 +03:00
case OPT_VERSION :
2011-05-16 21:13:11 +04:00
daemonVersion ( argv [ 0 ] ) ;
2008-12-12 10:56:50 +03:00
return 0 ;
2007-02-14 04:40:09 +03:00
case ' ? ' :
2011-05-16 21:13:11 +04:00
daemonUsage ( argv [ 0 ] , privileged ) ;
2007-02-14 04:40:09 +03:00
return 2 ;
default :
2010-05-20 23:40:54 +04:00
fprintf ( stderr , _ ( " %s: internal error: unknown flag: %c \n " ) ,
2011-05-16 21:13:11 +04:00
argv [ 0 ] , c ) ;
2009-12-15 11:43:29 +03:00
exit ( EXIT_FAILURE ) ;
2007-02-14 04:40:09 +03:00
}
}
2011-05-16 21:13:11 +04:00
if ( ! ( config = daemonConfigNew ( privileged ) ) )
exit ( EXIT_FAILURE ) ;
/* No explicit config, so try and find a default one */
if ( remote_config_file = = NULL & &
daemonConfigFilePath ( privileged ,
& remote_config_file ) < 0 )
exit ( EXIT_FAILURE ) ;
/* Read the config file if it exists*/
if ( remote_config_file & &
daemonConfigLoad ( config , remote_config_file ) < 0 )
exit ( EXIT_FAILURE ) ;
if ( config - > host_uuid & &
virSetHostUUIDStr ( config - > host_uuid ) < 0 ) {
VIR_ERROR ( _ ( " invalid host UUID: %s " ) , config - > host_uuid ) ;
exit ( EXIT_FAILURE ) ;
2009-01-12 21:22:32 +03:00
}
2011-05-16 21:13:11 +04:00
if ( daemonSetupLogging ( config , privileged , verbose , godaemon ) < 0 )
exit ( EXIT_FAILURE ) ;
if ( ! pid_file & & privileged & &
daemonPidFilePath ( privileged ,
& pid_file ) < 0 )
exit ( EXIT_FAILURE ) ;
if ( daemonUnixSocketPaths ( config ,
privileged ,
& sock_file ,
& sock_file_ro ) < 0 )
exit ( EXIT_FAILURE ) ;
2008-05-20 20:17:36 +04:00
if ( godaemon ) {
2009-02-05 19:28:03 +03:00
char ebuf [ 1024 ] ;
2010-12-13 13:18:45 +03:00
if ( chdir ( " / " ) < 0 ) {
VIR_ERROR ( _ ( " cannot change to root directory: %s " ) ,
virStrerror ( errno , ebuf , sizeof ( ebuf ) ) ) ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
2010-12-13 13:18:45 +03:00
}
2011-05-16 21:13:11 +04:00
if ( ( statuswrite = daemonForkIntoBackground ( argv [ 0 ] ) ) < 0 ) {
2009-02-05 19:28:03 +03:00
VIR_ERROR ( _ ( " Failed to fork as daemon: %s " ) ,
virStrerror ( errno , ebuf , sizeof ebuf ) ) ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
2008-05-20 20:17:36 +04:00
}
}
/* If we have a pidfile set, claim it now, exiting if already taken */
if ( pid_file ! = NULL & &
2011-05-16 21:13:11 +04:00
daemonWritePidFile ( pid_file , argv [ 0 ] ) < 0 ) {
VIR_FREE ( pid_file ) ; /* Prevent unlinking of someone else's pid ! */
2009-10-16 15:14:54 +04:00
ret = VIR_DAEMON_ERR_PIDFILE ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
2009-10-16 15:14:54 +04:00
}
2008-05-20 20:17:36 +04:00
2009-01-22 20:49:41 +03:00
/* Ensure the rundir exists (on tmpfs on some systems) */
2011-05-16 21:13:11 +04:00
if ( privileged ) {
2010-11-16 17:54:17 +03:00
const char * rundir = LOCALSTATEDIR " /run/libvirt " ;
2011-03-09 16:15:48 +03:00
mode_t old_umask ;
2009-01-22 20:49:41 +03:00
2011-03-09 16:15:48 +03:00
old_umask = umask ( 022 ) ;
2009-01-22 20:49:41 +03:00
if ( mkdir ( rundir , 0755 ) ) {
if ( errno ! = EEXIST ) {
2009-09-23 14:38:21 +04:00
char ebuf [ 1024 ] ;
VIR_ERROR ( _ ( " unable to create rundir %s: %s " ) , rundir ,
virStrerror ( errno , ebuf , sizeof ( ebuf ) ) ) ;
2009-10-16 15:14:54 +04:00
ret = VIR_DAEMON_ERR_RUNDIR ;
2011-03-09 16:15:48 +03:00
umask ( old_umask ) ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
2009-01-22 20:49:41 +03:00
}
}
2011-03-09 16:15:48 +03:00
umask ( old_umask ) ;
2009-01-22 20:49:41 +03:00
}
2011-05-16 21:13:11 +04:00
if ( ! ( srv = virNetServerNew ( config - > min_workers ,
config - > max_workers ,
config - > max_clients ,
config - > mdns_adv ? config - > mdns_name : NULL ,
remoteClientInitHook ) ) ) {
ret = VIR_DAEMON_ERR_INIT ;
goto cleanup ;
}
2009-06-12 17:20:13 +04:00
/* Beyond this point, nothing should rely on using
* getuid / geteuid ( ) = = 0 , for privilege level checks .
*/
2011-05-16 21:13:11 +04:00
if ( daemonSetupPrivs ( ) < 0 ) {
2009-10-16 15:14:54 +04:00
ret = VIR_DAEMON_ERR_PRIVS ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
2009-10-16 15:14:54 +04:00
}
2009-01-22 20:49:41 +03:00
2011-05-16 21:13:11 +04:00
daemonInitialize ( ) ;
2011-02-17 16:17:59 +03:00
2011-05-16 21:13:11 +04:00
remoteProcs [ REMOTE_PROC_AUTH_LIST ] . needAuth = false ;
remoteProcs [ REMOTE_PROC_AUTH_SASL_INIT ] . needAuth = false ;
remoteProcs [ REMOTE_PROC_AUTH_SASL_STEP ] . needAuth = false ;
remoteProcs [ REMOTE_PROC_AUTH_SASL_START ] . needAuth = false ;
remoteProcs [ REMOTE_PROC_AUTH_POLKIT ] . needAuth = false ;
if ( ! ( remoteProgram = virNetServerProgramNew ( REMOTE_PROGRAM ,
REMOTE_PROTOCOL_VERSION ,
remoteProcs ,
remoteNProcs ) ) ) {
2009-10-16 15:14:54 +04:00
ret = VIR_DAEMON_ERR_INIT ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
}
if ( virNetServerAddProgram ( srv , remoteProgram ) < 0 ) {
ret = VIR_DAEMON_ERR_INIT ;
goto cleanup ;
2007-12-05 18:34:05 +03:00
}
2007-02-16 21:28:17 +03:00
2011-05-16 21:13:11 +04:00
if ( ! ( qemuProgram = virNetServerProgramNew ( QEMU_PROGRAM ,
QEMU_PROTOCOL_VERSION ,
qemuProcs ,
qemuNProcs ) ) ) {
ret = VIR_DAEMON_ERR_INIT ;
goto cleanup ;
}
if ( virNetServerAddProgram ( srv , qemuProgram ) < 0 ) {
ret = VIR_DAEMON_ERR_INIT ;
goto cleanup ;
2009-10-16 15:14:54 +04:00
}
2009-10-16 14:48:50 +04:00
2011-05-16 21:13:11 +04:00
if ( timeout ! = - 1 )
virNetServerAutoShutdown ( srv ,
timeout ,
daemonShutdownCheck ,
NULL ) ;
if ( ( daemonSetupSignals ( srv ) ) < 0 ) {
ret = VIR_DAEMON_ERR_SIGNAL ;
goto cleanup ;
2009-10-16 15:14:54 +04:00
}
2007-02-14 04:40:09 +03:00
2011-05-16 21:13:11 +04:00
if ( config - > audit_level ) {
2010-09-15 17:44:11 +04:00
if ( virAuditOpen ( ) < 0 ) {
2011-05-16 21:13:11 +04:00
if ( config - > audit_level > 1 ) {
2010-09-15 17:44:11 +04:00
ret = VIR_DAEMON_ERR_AUDIT ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
2010-09-15 17:44:11 +04:00
}
}
}
2011-05-16 21:13:11 +04:00
virAuditLog ( config - > audit_logging ) ;
2010-09-15 17:44:11 +04:00
2010-03-26 17:53:32 +03:00
/* setup the hooks if any */
2010-03-30 17:06:13 +04:00
if ( virHookInitialize ( ) < 0 ) {
2010-03-26 17:53:32 +03:00
ret = VIR_DAEMON_ERR_HOOKS ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
2010-03-26 17:53:32 +03:00
}
2009-10-19 21:28:28 +04:00
/* Disable error func, now logging is setup */
2011-05-16 21:13:11 +04:00
virSetErrorFunc ( NULL , daemonErrorHandler ) ;
2011-01-21 20:25:01 +03:00
virSetErrorLogPriorityFunc ( daemonErrorLogFilter ) ;
2009-10-19 21:28:28 +04:00
2010-03-26 17:53:32 +03:00
/*
* Call the daemon startup hook
* TODO : should we abort the daemon startup if the script returned
* an error ?
*/
virHookCall ( VIR_HOOK_DRIVER_DAEMON , " - " , VIR_HOOK_DAEMON_OP_START ,
0 , " start " , NULL ) ;
2011-05-16 21:13:11 +04:00
if ( daemonSetupNetworking ( srv , config ,
sock_file , sock_file_ro ,
ipsock , privileged ) < 0 ) {
2009-10-16 15:14:54 +04:00
ret = VIR_DAEMON_ERR_NETWORK ;
2011-05-16 21:13:11 +04:00
goto cleanup ;
2007-12-05 18:34:05 +03:00
}
2009-10-16 15:14:54 +04:00
/* Tell parent of daemon that basic initialization is complete
* In particular we ' re ready to accept net connections & have
* written the pidfile
*/
if ( statuswrite ! = - 1 ) {
char status = 0 ;
while ( write ( statuswrite , & status , 1 ) = = - 1 & &
errno = = EINTR )
;
2010-11-09 23:48:48 +03:00
VIR_FORCE_CLOSE ( statuswrite ) ;
2009-10-16 15:14:54 +04:00
}
2011-05-16 21:13:11 +04:00
/* Initialize drivers & then start accepting new clients from network */
if ( daemonStateInit ( srv ) < 0 ) {
ret = VIR_DAEMON_ERR_INIT ;
goto cleanup ;
2009-10-16 15:14:54 +04:00
}
2007-02-14 04:40:09 +03:00
2011-05-16 21:13:11 +04:00
/* Run event loop. */
virNetServerRun ( srv ) ;
2009-10-16 19:34:37 +04:00
2007-02-23 15:48:36 +03:00
ret = 0 ;
2010-03-26 17:53:32 +03:00
virHookCall ( VIR_HOOK_DRIVER_DAEMON , " - " , VIR_HOOK_DAEMON_OP_SHUTDOWN ,
0 , " shutdown " , NULL ) ;
2011-05-16 21:13:11 +04:00
cleanup :
virNetServerProgramFree ( remoteProgram ) ;
virNetServerProgramFree ( qemuProgram ) ;
virNetServerFree ( srv ) ;
2009-10-16 15:14:54 +04:00
if ( statuswrite ! = - 1 ) {
if ( ret ! = 0 ) {
/* Tell parent of daemon what failed */
char status = ret ;
while ( write ( statuswrite , & status , 1 ) = = - 1 & &
errno = = EINTR )
;
}
2010-11-09 23:48:48 +03:00
VIR_FORCE_CLOSE ( statuswrite ) ;
2009-10-16 15:14:54 +04:00
}
2008-05-20 20:17:36 +04:00
if ( pid_file )
unlink ( pid_file ) ;
2011-05-16 21:13:11 +04:00
VIR_FREE ( sock_file ) ;
VIR_FREE ( sock_file_ro ) ;
VIR_FREE ( pid_file ) ;
VIR_FREE ( remote_config_file ) ;
daemonConfigFree ( config ) ;
virLogShutdown ( ) ;
2007-02-23 15:48:36 +03:00
return ret ;
2007-02-14 04:40:09 +03:00
}