2007-02-14 01:40:09 +00:00
/*
2009-09-16 12:37:26 +01:00
* libvirtd . c : daemon start of day , guest process & i / o management
2007-02-14 01:40:09 +00:00
*
2011-02-16 16:37:57 -07:00
* Copyright ( C ) 2006 - 2011 Red Hat , Inc .
2007-02-14 01:40:09 +00: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 18:15:54 +00:00
# include <config.h>
2007-02-14 15:42:55 +00:00
2007-02-14 01:40:09 +00:00
# include <unistd.h>
# include <fcntl.h>
2011-05-16 18:13:11 +01:00
# include <sys/wait.h>
# include <sys/stat.h>
2007-02-14 01:40:09 +00:00
# include <getopt.h>
2011-05-16 18:13:11 +01:00
# include <stdlib.h>
2007-09-19 02:28:01 +00:00
# include <grp.h>
2010-11-16 12:01:37 -07:00
# include <locale.h>
2007-04-10 23:17:46 +00:00
2008-11-04 23:22:06 +00:00
# include "libvirt_internal.h"
2009-02-05 16:28:30 +00:00
# include "virterror_internal.h"
2011-07-19 12:32:58 -06:00
# include "virfile.h"
2011-08-05 15:11:11 +01:00
# include "virpidfile.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 08:24:41 +00:00
2009-02-09 17:52:38 +00:00
# define VIR_FROM_THIS VIR_FROM_QEMU
2009-09-16 12:37:26 +01:00
# include "libvirtd.h"
2009-07-10 12:20:03 +01: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 08:24:41 +00:00
# include "util.h"
2010-05-25 15:33:51 +01:00
# include "uuid.h"
2009-09-16 16:55:16 +01: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 08:24:41 +00:00
# include "conf.h"
2008-06-06 10:52:01 +00:00
# include "memory.h"
2011-05-16 18:13:11 +01:00
# include "conf.h"
# include "virnetserver.h"
# include "threads.h"
# include "remote.h"
# include "remote_driver.h"
2010-03-26 15:53:32 +01:00
# include "hooks.h"
2011-05-16 18:13:11 +01:00
# include "uuid.h"
2011-07-11 13:42:15 -06:00
# include "viraudit.h"
2007-02-14 01:40:09 +00:00
2008-11-21 12:16:08 +00:00
# ifdef WITH_DRIVER_MODULES
2010-03-09 19:22:22 +01:00
# include "driver.h"
2008-11-21 12:16:08 +00:00
# else
2010-03-09 19:22:22 +01:00
# ifdef WITH_QEMU
# include "qemu / qemu_driver.h"
# endif
# ifdef WITH_LXC
# include "lxc / lxc_driver.h"
# endif
2011-02-10 15:42:34 -07:00
# ifdef WITH_LIBXL
# include "libxl / libxl_driver.h"
# endif
2010-03-09 19:22:22 +01: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 13:46:09 -04:00
# ifdef WITH_NWFILTER
# include "nwfilter / nwfilter_driver.h"
# endif
2009-12-22 14:50:50 +01:00
# endif
2008-11-17 12:18:18 +00:00
2010-11-16 07:54:17 -07:00
# include "configmake.h"
2011-06-30 18:18:08 +01:00
# if HAVE_SASL
2011-05-16 18:13:11 +01:00
virNetSASLContextPtr saslCtxt = NULL ;
2011-06-30 18:18:08 +01:00
# endif
2011-05-16 18:13:11 +01:00
virNetServerProgramPtr remoteProgram = NULL ;
virNetServerProgramPtr qemuProgram = NULL ;
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
struct daemonConfig {
char * host_uuid ;
2009-02-09 17:52:38 +00:00
2011-05-16 18:13:11 +01:00
int listen_tls ;
int listen_tcp ;
char * listen_addr ;
char * tls_port ;
char * tcp_port ;
2007-12-05 15:34:05 +00:00
2011-05-16 18:13:11 +01:00
char * unix_sock_ro_perms ;
char * unix_sock_rw_perms ;
char * unix_sock_group ;
char * unix_sock_dir ;
2007-09-19 01:56:55 +00:00
2011-05-16 18:13:11 +01:00
int auth_unix_rw ;
int auth_unix_ro ;
int auth_tcp ;
int auth_tls ;
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
int mdns_adv ;
char * mdns_name ;
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
int tls_no_verify_certificate ;
2011-07-21 11:13:11 +01:00
int tls_no_sanity_certificate ;
2011-05-16 18:13:11 +01:00
char * * tls_allowed_dn_list ;
char * * sasl_allowed_username_list ;
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
char * key_file ;
char * cert_file ;
char * ca_file ;
char * crl_file ;
2008-12-04 22:18:44 +00:00
2011-05-16 18:13:11 +01:00
int min_workers ;
int max_workers ;
int max_clients ;
2009-01-20 19:25:15 +00:00
2011-08-12 14:04:31 +02:00
int prio_workers ;
2011-05-16 18:13:11 +01:00
int max_requests ;
int max_client_requests ;
2010-09-15 14:44:11 +01:00
2011-05-16 18:13:11 +01:00
int log_level ;
char * log_filters ;
char * log_outputs ;
int log_buffer_size ;
2007-02-16 18:28:17 +00:00
2011-05-16 18:13:11 +01:00
int audit_level ;
int audit_logging ;
2011-08-24 15:33:34 +02:00
int keepalive_interval ;
unsigned int keepalive_count ;
int keepalive_required ;
2011-05-16 18:13:11 +01:00
} ;
2007-03-27 10:28:45 +00:00
2009-10-16 12:14:54 +01: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 15:53:32 +01:00
VIR_DAEMON_ERR_HOOKS ,
2010-09-15 14:44:11 +01:00
VIR_DAEMON_ERR_AUDIT ,
2009-10-16 12:14:54 +01: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 15:53:32 +01:00
" Unable to load configuration file " ,
2010-09-15 14:44:11 +01:00
" Unable to look for hook scripts " ,
" Unable to initialize audit system " )
2009-10-16 12:14:54 +01:00
2011-05-16 18:13:11 +01:00
static int daemonForkIntoBackground ( const char * argv0 )
2007-06-11 12:04:54 +00:00
{
2009-10-16 12:14:54 +01:00
int statuspipe [ 2 ] ;
if ( pipe ( statuspipe ) < 0 )
return - 1 ;
2007-02-14 01:40:09 +00:00
int pid = fork ( ) ;
switch ( pid ) {
case 0 :
{
int stdinfd = - 1 ;
int stdoutfd = - 1 ;
2007-02-16 18:26:18 +00:00
int nextpid ;
2007-02-14 01:40:09 +00:00
2010-11-09 15:48:48 -05:00
VIR_FORCE_CLOSE ( statuspipe [ 0 ] ) ;
2009-10-16 12:14:54 +01:00
2008-12-17 18:04:55 +00:00
if ( ( stdinfd = open ( " /dev/null " , O_RDONLY ) ) < 0 )
2007-02-14 01:40:09 +00:00
goto cleanup ;
2008-12-17 18:04:55 +00:00
if ( ( stdoutfd = open ( " /dev/null " , O_WRONLY ) ) < 0 )
2007-02-14 01:40:09 +00: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 15:48:48 -05:00
if ( VIR_CLOSE ( stdinfd ) < 0 )
2007-02-14 01:40:09 +00:00
goto cleanup ;
2010-11-09 15:48:48 -05:00
if ( VIR_CLOSE ( stdoutfd ) < 0 )
2007-02-14 01:40:09 +00:00
goto cleanup ;
if ( setsid ( ) < 0 )
goto cleanup ;
nextpid = fork ( ) ;
switch ( nextpid ) {
case 0 :
2009-10-16 12:14:54 +01:00
return statuspipe [ 1 ] ;
2007-02-14 01:40:09 +00:00
case - 1 :
return - 1 ;
default :
2008-03-11 14:22:12 +00:00
_exit ( 0 ) ;
2007-02-14 01:40:09 +00:00
}
cleanup :
2010-11-09 15:48:48 -05:00
VIR_FORCE_CLOSE ( stdoutfd ) ;
VIR_FORCE_CLOSE ( stdinfd ) ;
2007-02-14 01:40:09 +00:00
return - 1 ;
}
case - 1 :
return - 1 ;
default :
{
2009-10-16 12:14:54 +01:00
int ret ;
char status ;
2010-11-09 15:48:48 -05:00
VIR_FORCE_CLOSE ( statuspipe [ 1 ] ) ;
2009-10-16 12:14:54 +01:00
/* We wait to make sure the first child forked successfully */
2011-10-21 11:09:23 -06:00
if ( virPidWait ( pid , NULL ) < 0 )
2007-02-14 01:40:09 +00:00
return - 1 ;
2009-10-16 12:14:54 +01: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 11:29:35 -05:00
fprintf ( stderr ,
2010-05-20 21:40:54 +02:00
_ ( " %s: error: %s. Check /var/log/messages or run without "
" --daemon for more info. \n " ) , argv0 ,
2010-02-24 11:29:35 -05:00
virDaemonErrTypeToString ( status ) ) ;
2009-10-16 12:14:54 +01:00
}
_exit ( ret = = 1 & & status = = 0 ? 0 : 1 ) ;
2007-02-14 01:40:09 +00:00
}
}
}
2007-06-11 12:04:54 +00:00
static int
2011-05-16 18:13:11 +01:00
daemonPidFilePath ( bool privileged ,
char * * pidfile )
2007-06-11 12:04:54 +00:00
{
2011-05-16 18:13:11 +01:00
if ( privileged ) {
if ( ! ( * pidfile = strdup ( LOCALSTATEDIR " /run/libvirtd.pid " ) ) )
goto no_memory ;
} else {
char * userdir = NULL ;
2007-09-19 01:56:55 +00:00
2011-05-16 18:13:11 +01:00
if ( ! ( userdir = virGetUserDirectory ( geteuid ( ) ) ) )
goto error ;
2007-09-19 01:56:55 +00:00
2011-06-30 17:08:41 -06:00
if ( virAsprintf ( pidfile , " %s/.libvirt/libvirtd.pid " , userdir ) < 0 ) {
VIR_FREE ( userdir ) ;
2011-05-16 18:13:11 +01:00
goto no_memory ;
2011-06-30 17:08:41 -06:00
}
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
VIR_FREE ( userdir ) ;
2007-06-11 12:04:54 +00:00
}
return 0 ;
2008-06-06 10:52:01 +00:00
2011-05-16 18:13:11 +01:00
no_memory :
virReportOOMError ( ) ;
error :
2008-06-06 10:52:01 +00:00
return - 1 ;
2007-06-11 12:04:54 +00:00
}
2011-05-16 18:13:11 +01:00
static int
daemonUnixSocketPaths ( struct daemonConfig * config ,
bool privileged ,
char * * sockfile ,
char * * rosockfile )
2009-01-22 17:49:41 +00:00
{
2011-05-16 18:13:11 +01:00
if ( config - > unix_sock_dir ) {
if ( virAsprintf ( sockfile , " %s/libvirt-sock " , config - > unix_sock_dir ) < 0 )
2010-06-03 14:36:34 +01:00
goto no_memory ;
2011-05-16 18:13:11 +01:00
if ( privileged & &
virAsprintf ( rosockfile , " %s/libvirt-sock-ro " , config - > unix_sock_dir ) < 0 )
2010-06-03 14:36:34 +01:00
goto no_memory ;
2009-10-16 11:29:01 +01:00
} else {
2011-05-16 18:13:11 +01:00
if ( privileged ) {
if ( ! ( * sockfile = strdup ( LOCALSTATEDIR " /run/libvirt/libvirt-sock " ) ) )
2010-06-03 14:36:34 +01:00
goto no_memory ;
2011-05-16 18:13:11 +01:00
if ( ! ( * rosockfile = strdup ( LOCALSTATEDIR " /run/libvirt/libvirt-sock-ro " ) ) )
2010-06-03 14:36:34 +01:00
goto no_memory ;
2011-05-16 18:13:11 +01:00
} else {
char * userdir = NULL ;
2007-02-16 18:30:55 +00:00
2011-05-16 18:13:11 +01:00
if ( ! ( userdir = virGetUserDirectory ( geteuid ( ) ) ) )
goto error ;
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
if ( virAsprintf ( sockfile , " @%s/.libvirt/libvirt-sock " , userdir ) < 0 ) {
VIR_FREE ( userdir ) ;
goto no_memory ;
}
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
VIR_FREE ( userdir ) ;
}
}
return 0 ;
2007-02-16 18:30:55 +00:00
2010-06-03 14:36:34 +01:00
no_memory :
2011-05-16 18:13:11 +01:00
virReportOOMError ( ) ;
error :
return - 1 ;
2007-02-14 01:40:09 +00:00
}
2011-05-16 18:13:11 +01:00
static void daemonErrorHandler ( void * opaque ATTRIBUTE_UNUSED ,
virErrorPtr err ATTRIBUTE_UNUSED )
2009-10-19 18:28:28 +01:00
{
/* Don't do anything, since logging infrastructure already
* took care of reporting the error */
}
2011-01-21 17:25:01 +00: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 :
2011-09-13 18:24:13 +08:00
case VIR_ERR_OPERATION_INVALID :
2011-01-21 17:25:01 +00:00
return VIR_LOG_DEBUG ;
}
return priority ;
}
2011-05-16 18:13:11 +01:00
static void daemonInitialize ( void )
{
2008-12-02 11:37:55 +00: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 12:16:08 +00: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 00:02:46 +01:00
* If they try to open a connection for a module that
2008-11-21 12:16:08 +00:00
* is not loaded they ' ll get a suitable error at that point
*/
virDriverLoadModule ( " network " ) ;
virDriverLoadModule ( " storage " ) ;
2008-11-21 12:27:11 +00:00
virDriverLoadModule ( " nodedev " ) ;
2009-08-14 21:48:55 +02:00
virDriverLoadModule ( " secret " ) ;
2008-12-02 11:37:55 +00:00
virDriverLoadModule ( " qemu " ) ;
virDriverLoadModule ( " lxc " ) ;
virDriverLoadModule ( " uml " ) ;
2010-03-25 13:46:09 -04:00
virDriverLoadModule ( " nwfilter " ) ;
2008-11-21 12:16:08 +00:00
# else
2010-03-09 19:22:22 +01:00
# ifdef WITH_NETWORK
2008-11-17 12:18:18 +00:00
networkRegister ( ) ;
2010-03-09 19:22:22 +01:00
# endif
# ifdef WITH_NETCF
2009-07-21 16:02:16 +02:00
interfaceRegister ( ) ;
2010-03-09 19:22:22 +01:00
# endif
# ifdef WITH_STORAGE_DIR
2008-11-17 12:18:18 +00:00
storageRegister ( ) ;
2010-03-09 19:22:22 +01:00
# endif
# if defined(WITH_NODE_DEVICES)
2008-11-21 12:27:11 +00:00
nodedevRegister ( ) ;
2010-03-09 19:22:22 +01:00
# endif
# ifdef WITH_SECRETS
2009-08-14 21:48:55 +02:00
secretRegister ( ) ;
2010-03-09 19:22:22 +01:00
# endif
2010-03-25 13:46:09 -04:00
# ifdef WITH_NWFILTER
nwfilterRegister ( ) ;
# endif
2011-02-10 15:42:34 -07:00
# ifdef WITH_LIBXL
libxlRegister ( ) ;
# endif
2010-03-09 19:22:22 +01:00
# ifdef WITH_QEMU
2008-12-02 11:37:55 +00:00
qemuRegister ( ) ;
2010-03-09 19:22:22 +01:00
# endif
# ifdef WITH_LXC
2008-12-02 11:37:55 +00:00
lxcRegister ( ) ;
2010-03-09 19:22:22 +01:00
# endif
# ifdef WITH_UML
2008-12-02 11:37:55 +00:00
umlRegister ( ) ;
2010-03-09 19:22:22 +01:00
# endif
2008-11-17 12:18:18 +00:00
# endif
2007-12-05 15:34:05 +00:00
}
2011-05-16 18:13:11 +01: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 15:34:05 +00:00
2011-05-16 18:13:11 +01: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 15:34:05 +00:00
2011-05-16 18:13:11 +01: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 15:34:05 +00:00
2011-05-16 18:13:11 +01:00
if ( ! ( svc = virNetServerServiceNewUNIX ( sock_path ,
unix_sock_rw_mask ,
unix_sock_gid ,
config - > auth_unix_rw ,
false ,
2011-06-30 11:45:55 +01:00
config - > max_client_requests ,
2011-05-16 18:13:11 +01: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 11:45:55 +01:00
config - > max_client_requests ,
2011-05-16 18:13:11 +01:00
NULL ) ) )
goto error ;
2009-03-02 11:13:37 +00:00
2011-10-11 20:48:42 +08:00
if ( virNetServerAddService ( srv , svc ,
config - > mdns_adv & & ! ipsock ?
" _libvirt._tcp " :
NULL ) < 0 )
2011-05-16 18:13:11 +01:00
goto error ;
2011-10-11 20:48:42 +08:00
2011-05-16 18:13:11 +01:00
if ( svcRO & &
virNetServerAddService ( srv , svcRO , NULL ) < 0 )
goto error ;
2007-12-05 18:21:27 +00:00
2007-06-26 23:48:46 +00:00
if ( ipsock ) {
2011-05-16 18:13:11 +01:00
if ( config - > listen_tcp ) {
if ( ! ( svcTCP = virNetServerServiceNewTCP ( config - > listen_addr ,
config - > tcp_port ,
config - > auth_tcp ,
false ,
2011-06-30 11:45:55 +01:00
config - > max_client_requests ,
2011-05-16 18:13:11 +01:00
NULL ) ) )
goto error ;
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
if ( virNetServerAddService ( srv , svcTCP ,
config - > mdns_adv ? " _libvirt._tcp " : NULL ) < 0 )
goto error ;
2007-06-11 12:04:54 +00:00
}
2011-05-16 18:13:11 +01:00
if ( config - > listen_tls ) {
virNetTLSContextPtr ctxt = NULL ;
2010-09-14 17:50:25 +01:00
2011-05-16 18:13:11 +01: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 ,
2011-07-21 11:13:11 +01:00
config - > tls_no_sanity_certificate ? false : true ,
2011-05-16 18:13:11 +01:00
config - > tls_no_verify_certificate ? false : true ) ) )
goto error ;
} else {
if ( ! ( ctxt = virNetTLSContextNewServerPath ( NULL ,
! privileged ,
( const char * const * ) config - > tls_allowed_dn_list ,
2011-07-21 11:13:11 +01:00
config - > tls_no_sanity_certificate ? false : true ,
2011-05-16 18:13:11 +01:00
config - > tls_no_verify_certificate ? false : true ) ) )
goto error ;
2010-09-14 17:50:25 +01:00
}
2011-05-16 18:13:11 +01:00
if ( ! ( svcTLS =
virNetServerServiceNewTCP ( config - > listen_addr ,
config - > tls_port ,
config - > auth_tls ,
false ,
2011-06-30 11:45:55 +01:00
config - > max_client_requests ,
2011-05-16 18:13:11 +01:00
ctxt ) ) ) {
virNetTLSContextFree ( ctxt ) ;
goto error ;
2010-09-14 17:50:25 +01:00
}
2011-05-16 18:13:11 +01: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 15:43:42 +00:00
2011-05-16 18:13:11 +01:00
virNetTLSContextFree ( ctxt ) ;
2007-06-11 12:04:54 +00:00
}
}
2011-06-30 18:18:08 +01:00
# if HAVE_SASL
2011-05-16 18:13:11 +01: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 17:50:25 +01:00
goto error ;
2007-02-14 01:40:09 +00:00
}
2011-06-30 18:18:08 +01:00
# endif
2007-02-14 01:40:09 +00:00
return 0 ;
2007-06-11 12:04:54 +00:00
2010-09-14 17:50:25 +01:00
error :
2011-05-16 18:13:11 +01:00
virNetServerServiceFree ( svcTLS ) ;
virNetServerServiceFree ( svcTCP ) ;
virNetServerServiceFree ( svc ) ;
virNetServerServiceFree ( svcRO ) ;
2007-06-11 12:04:54 +00:00
return - 1 ;
2007-02-14 01:40:09 +00:00
}
2011-05-16 18:13:11 +01:00
static int daemonShutdownCheck ( virNetServerPtr srv ATTRIBUTE_UNUSED ,
void * opaque ATTRIBUTE_UNUSED )
2010-12-10 17:35:58 -07:00
{
2011-05-16 18:13:11 +01:00
if ( virStateActive ( ) )
return 0 ;
2009-01-15 19:56:05 +00:00
2011-05-16 18:13:11 +01:00
return 1 ;
2007-02-14 01:40:09 +00:00
}
2011-05-16 18:13:11 +01: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 15:43:42 +00: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 10:52:01 +00:00
if ( VIR_ALLOC_N ( list , 2 ) < 0 ) {
2009-01-06 18:32:03 +00: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 15:43:42 +00:00
return - 1 ;
}
list [ 0 ] = strdup ( p - > str ) ;
list [ 1 ] = NULL ;
if ( list [ 0 ] = = NULL ) {
2009-01-06 18:32:03 +00: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 15:43:42 +00:00
key ) ;
2008-06-06 10:52:01 +00: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 15:43:42 +00: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 10:52:01 +00:00
if ( VIR_ALLOC_N ( list , 1 + len ) < 0 ) {
2009-01-06 18:32:03 +00: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 15:43:42 +00:00
return - 1 ;
}
for ( i = 0 , pp = p - > list ; pp ; + + i , pp = pp - > next ) {
if ( pp - > type ! = VIR_CONF_STRING ) {
2009-01-06 18:32:03 +00:00
VIR_ERROR ( _ ( " remoteReadConfigFile: %s: %s: "
2010-04-02 21:44:04 +02: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 15:43:42 +00:00
filename , key ) ;
2008-06-06 10:52:01 +00: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 15:43:42 +00:00
return - 1 ;
}
list [ i ] = strdup ( pp - > str ) ;
if ( list [ i ] = = NULL ) {
int j ;
for ( j = 0 ; j < i ; j + + )
2008-06-06 10:52:01 +00:00
VIR_FREE ( list [ j ] ) ;
VIR_FREE ( list ) ;
2009-01-06 18:32:03 +00: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 15:43:42 +00:00
return - 1 ;
}
}
list [ i ] = NULL ;
break ;
}
default :
2009-01-06 18:32:03 +00:00
VIR_ERROR ( _ ( " remoteReadConfigFile: %s: %s: "
2010-04-02 21:44:04 +02: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 15:43:42 +00: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 18:32:03 +00:00
VIR_ERROR ( _ ( " remoteReadConfigFile: %s: %s: invalid type: "
2010-04-02 21:44:04 +02: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 15:43:42 +00: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 18:13:11 +01: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 15:43:42 +00: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 18:13:11 +01: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 15:43:42 +00:00
} \
} while ( 0 )
2007-12-05 15:34:05 +00: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-11 21:20:13 +00:00
if ( checkType ( p , filename , key , VIR_CONF_STRING ) < 0 )
2007-12-05 15:34:05 +00:00
return - 1 ;
if ( ! p - > str )
return 0 ;
if ( STREQ ( p - > str , " none " ) ) {
2011-05-16 18:13:11 +01:00
* auth = VIR_NET_SERVER_SERVICE_AUTH_NONE ;
2011-06-30 18:18:08 +01:00
# if HAVE_SASL
2007-12-05 15:34:05 +00:00
} else if ( STREQ ( p - > str , " sasl " ) ) {
2011-05-16 18:13:11 +01:00
* auth = VIR_NET_SERVER_SERVICE_AUTH_SASL ;
2011-06-30 18:18:08 +01:00
# endif
2007-12-05 18:21:27 +00:00
} else if ( STREQ ( p - > str , " polkit " ) ) {
2011-05-16 18:13:11 +01:00
* auth = VIR_NET_SERVER_SERVICE_AUTH_POLKIT ;
2007-12-05 15:34:05 +00:00
} else {
2010-01-19 14:17:20 +01: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 16:50:17 +00:00
filename , key , p - > str ) ;
2007-12-05 15:34:05 +00:00
return - 1 ;
}
return 0 ;
}
2008-12-22 12:53:26 +00:00
/*
* Set up the logging environment
2011-03-03 14:48:06 +08: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 18:31:20 +08:00
* informational and debug messages . Default size if 64 kB .
2008-12-22 12:53:26 +00:00
*/
2008-12-22 16:16:10 +00:00
static int
2011-05-16 18:13:11 +01:00
daemonSetupLogging ( struct daemonConfig * config ,
bool privileged ,
bool verbose ,
bool godaemon )
2009-10-23 08:56:21 +02:00
{
2008-12-22 12:53:26 +00:00
virLogReset ( ) ;
2008-12-22 16:16:10 +00:00
/*
2009-08-06 15:55:07 +02: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 16:16:10 +00:00
*/
2011-05-16 18:13:11 +01:00
if ( config - > log_level ! = 0 )
virLogSetDefaultPriority ( config - > log_level ) ;
2009-08-06 15:45:50 +02:00
2009-08-06 15:55:07 +02:00
virLogSetFromEnv ( ) ;
2009-08-06 15:45:50 +02:00
2011-05-16 18:13:11 +01:00
virLogSetBufferSize ( config - > log_buffer_size ) ;
2008-12-22 12:53:26 +00:00
2011-05-16 18:13:11 +01:00
if ( virLogGetNbFilters ( ) = = 0 )
virLogParseFilters ( config - > log_filters ) ;
if ( virLogGetNbOutputs ( ) = = 0 )
virLogParseOutputs ( config - > log_outputs ) ;
2008-12-22 12:53:26 +00:00
/*
2011-03-03 14:48:06 +08:00
* If no defined outputs , then direct to libvirtd . log when running
2009-08-06 15:45:50 +02:00
* as daemon . Otherwise the default output is stderr .
2008-12-22 12:53:26 +00:00
*/
2009-08-06 15:45:50 +02:00
if ( virLogGetNbOutputs ( ) = = 0 ) {
2009-07-01 11:21:15 +00:00
char * tmp = NULL ;
2011-03-03 14:48:06 +08:00
2009-01-20 21:50:31 +00:00
if ( godaemon ) {
2011-05-16 18:13:11 +01:00
if ( privileged ) {
2011-03-03 14:48:06 +08:00
if ( virAsprintf ( & tmp , " %d:file:%s/log/libvirt/libvirtd.log " ,
virLogGetDefaultPriority ( ) ,
LOCALSTATEDIR ) = = - 1 )
2011-05-16 18:13:11 +01:00
goto no_memory ;
2011-03-03 14:48:06 +08:00
} else {
char * userdir = virGetUserDirectory ( geteuid ( ) ) ;
if ( ! userdir )
2011-05-16 18:13:11 +01:00
goto error ;
2011-03-03 14:48:06 +08:00
if ( virAsprintf ( & tmp , " %d:file:%s/.libvirt/libvirtd.log " ,
2011-06-02 15:56:32 -06:00
virLogGetDefaultPriority ( ) , userdir ) = = - 1 ) {
VIR_FREE ( userdir ) ;
2011-05-16 18:13:11 +01:00
goto no_memory ;
2011-06-02 15:56:32 -06:00
}
2011-06-06 15:03:26 -06:00
VIR_FREE ( userdir ) ;
2011-03-03 14:48:06 +08:00
}
2009-01-20 21:50:31 +00:00
} else {
2011-03-03 14:48:06 +08:00
if ( virAsprintf ( & tmp , " %d:stderr " , virLogGetDefaultPriority ( ) ) < 0 )
2011-05-16 18:13:11 +01:00
goto no_memory ;
2009-01-20 21:50:31 +00:00
}
2009-07-01 11:21:15 +00:00
virLogParseOutputs ( tmp ) ;
VIR_FREE ( tmp ) ;
2009-06-03 10:36:17 +00:00
}
2009-08-06 15:55:07 +02:00
/*
* Command line override for - - verbose
*/
if ( ( verbose ) & & ( virLogGetDefaultPriority ( ) > VIR_LOG_INFO ) )
virLogSetDefaultPriority ( VIR_LOG_INFO ) ;
2011-05-16 18:13:11 +01:00
return 0 ;
no_memory :
virReportOOMError ( ) ;
error :
return - 1 ;
}
2008-12-22 16:16:10 +00:00
2011-05-16 18:13:11 +01: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 14:48:06 +08:00
2011-05-16 18:13:11 +01:00
no_memory :
2011-03-03 14:48:06 +08:00
virReportOOMError ( ) ;
2011-05-16 18:13:11 +01:00
error :
return - 1 ;
2011-03-03 14:48:06 +08:00
}
static void
2011-05-16 18:13:11 +01:00
daemonConfigFree ( struct daemonConfig * data ) ;
static struct daemonConfig *
2011-06-28 21:09:05 +02:00
daemonConfigNew ( bool privileged ATTRIBUTE_UNUSED )
2011-03-03 14:48:06 +08:00
{
2011-05-16 18:13:11 +01: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 ;
2011-08-12 14:04:31 +02:00
data - > prio_workers = 5 ;
2011-05-16 18:13:11 +01:00
data - > max_requests = 20 ;
data - > max_client_requests = 5 ;
data - > log_buffer_size = 64 ;
data - > audit_level = 1 ;
data - > audit_logging = 0 ;
2011-08-24 15:33:34 +02:00
data - > keepalive_interval = 5 ;
data - > keepalive_count = 5 ;
data - > keepalive_required = 0 ;
2011-05-16 18:13:11 +01:00
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 12:53:26 +00:00
}
2007-12-05 19:25:44 +00:00
2011-05-16 18:13:11 +01:00
2007-06-11 12:04:54 +00:00
/* Read the config file if it exists.
* Only used in the remote case , hence the name .
*/
static int
2011-05-16 18:13:11 +01:00
daemonConfigLoad ( struct daemonConfig * data ,
2011-07-08 11:44:25 -06:00
const char * filename ,
bool allow_missing )
2007-06-11 12:04:54 +00:00
{
virConfPtr conf ;
2011-07-08 11:44:25 -06:00
if ( allow_missing & &
access ( filename , R_OK ) = = - 1 & &
2011-07-08 15:27:42 +01:00
errno = = ENOENT )
return 0 ;
2009-06-19 12:34:30 +00:00
conf = virConfReadFile ( filename , 0 ) ;
2011-05-16 18:13:11 +01:00
if ( ! conf )
return - 1 ;
2008-12-22 12:53:26 +00:00
2007-12-05 18:56:27 +00: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 15:43:42 +00:00
GET_CONF_STR ( conf , filename , tls_port ) ;
GET_CONF_STR ( conf , filename , tcp_port ) ;
2008-05-14 20:57:20 +00:00
GET_CONF_STR ( conf , filename , listen_addr ) ;
2008-05-14 21:22:04 +00:00
2011-05-16 18:13:11 +01:00
if ( remoteConfigGetAuth ( conf , " auth_unix_rw " , & data - > auth_unix_rw , filename ) < 0 )
goto error ;
2007-12-05 18:21:27 +00: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 18:13:11 +01:00
if ( data - > auth_unix_rw = = REMOTE_AUTH_POLKIT ) {
VIR_FREE ( data - > unix_sock_rw_perms ) ;
2011-06-28 21:09:05 +02:00
if ( ! ( data - > unix_sock_rw_perms = strdup ( " 0777 " ) ) ) {
virReportOOMError ( ) ;
goto error ;
}
2011-05-16 18:13:11 +01:00
}
2007-12-05 18:21:27 +00:00
# endif
2011-05-16 18:13:11 +01: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 15:34:05 +00: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 15:43:42 +00: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 02:28:01 +00:00
2009-02-09 17:52:38 +00: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 15:43:42 +00:00
GET_CONF_INT ( conf , filename , mdns_adv ) ;
GET_CONF_STR ( conf , filename , mdns_name ) ;
2007-09-19 01:56:55 +00:00
2011-07-21 11:13:11 +01:00
GET_CONF_INT ( conf , filename , tls_no_sanity_certificate ) ;
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 15:43:42 +00:00
GET_CONF_INT ( conf , filename , tls_no_verify_certificate ) ;
2007-06-11 12:04:54 +00: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 15:43:42 +00: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 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
if ( remoteConfigGetStringList ( conf , " tls_allowed_dn_list " ,
& data - > tls_allowed_dn_list , filename ) < 0 )
goto error ;
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01:00
if ( remoteConfigGetStringList ( conf , " sasl_allowed_username_list " ,
& data - > sasl_allowed_username_list , filename ) < 0 )
goto error ;
2007-06-11 12:04:54 +00:00
2008-12-04 22:18:44 +00:00
GET_CONF_INT ( conf , filename , min_workers ) ;
GET_CONF_INT ( conf , filename , max_workers ) ;
GET_CONF_INT ( conf , filename , max_clients ) ;
2011-08-12 14:04:31 +02:00
GET_CONF_INT ( conf , filename , prio_workers ) ;
2009-01-20 19:25:15 +00:00
GET_CONF_INT ( conf , filename , max_requests ) ;
GET_CONF_INT ( conf , filename , max_client_requests ) ;
2010-09-15 14:44:11 +01:00
GET_CONF_INT ( conf , filename , audit_level ) ;
GET_CONF_INT ( conf , filename , audit_logging ) ;
2010-05-25 15:33:51 +01:00
GET_CONF_STR ( conf , filename , host_uuid ) ;
2011-05-16 18:13:11 +01: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 15:33:51 +01:00
2011-08-24 15:33:34 +02:00
GET_CONF_INT ( conf , filename , keepalive_interval ) ;
GET_CONF_INT ( conf , filename , keepalive_count ) ;
GET_CONF_INT ( conf , filename , keepalive_required ) ;
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 15:43:42 +00:00
virConfFree ( conf ) ;
return 0 ;
2007-06-11 12:04:54 +00:00
2011-05-16 18:13:11 +01: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 15:43:42 +00:00
virConfFree ( conf ) ;
return - 1 ;
2007-06-11 12:04:54 +00:00
}
2008-12-12 07:56:50 +00:00
/* Display version information. */
static void
2011-05-16 18:13:11 +01:00
daemonVersion ( const char * argv0 )
2008-12-12 07:56:50 +00:00
{
printf ( " %s (%s) %s \n " , argv0 , PACKAGE_NAME , PACKAGE_VERSION ) ;
}
2009-01-22 17:49:41 +00:00
# ifdef __sun
static int
2011-05-16 18:13:11 +01:00
daemonSetupPrivs ( void )
2009-01-22 17:49:41 +00: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 17:24:09 +08:00
VIR_ERROR ( _ ( " additional privileges are required " ) ) ;
2009-01-22 17:49:41 +00: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 17:24:09 +08:00
VIR_ERROR ( _ ( " failed to set reduced privileges " ) ) ;
2009-01-22 17:49:41 +00:00
return - 1 ;
}
return 0 ;
}
# else
2011-05-16 18:13:11 +01:00
# define daemonSetupPrivs() 0
2009-01-22 17:49:41 +00:00
# endif
2009-10-16 11:48:50 +01:00
2011-05-16 18:13:11 +01:00
static void daemonShutdownHandler ( virNetServerPtr srv ,
siginfo_t * sig ATTRIBUTE_UNUSED ,
void * opaque ATTRIBUTE_UNUSED )
2009-10-16 11:48:50 +01:00
{
2011-05-16 18:13:11 +01:00
virNetServerQuit ( srv ) ;
}
2009-10-16 11:48:50 +01:00
2011-08-15 15:40:46 +08:00
static void daemonReloadHandler ( virNetServerPtr srv ATTRIBUTE_UNUSED ,
siginfo_t * sig ATTRIBUTE_UNUSED ,
void * opaque ATTRIBUTE_UNUSED )
{
VIR_INFO ( " Reloading configuration on SIGHUP " ) ;
virHookCall ( VIR_HOOK_DRIVER_DAEMON , " - " ,
VIR_HOOK_DAEMON_OP_RELOAD , SIGHUP , " SIGHUP " , NULL ) ;
if ( virStateReload ( ) < 0 )
VIR_WARN ( " Error while reloading drivers " ) ;
}
2011-05-16 18:13:11 +01:00
static int daemonSetupSignals ( virNetServerPtr srv )
{
if ( virNetServerAddSignalHandler ( srv , SIGINT , daemonShutdownHandler , NULL ) < 0 )
2009-10-16 11:48:50 +01:00
return - 1 ;
2011-05-16 18:13:11 +01:00
if ( virNetServerAddSignalHandler ( srv , SIGQUIT , daemonShutdownHandler , NULL ) < 0 )
return - 1 ;
if ( virNetServerAddSignalHandler ( srv , SIGTERM , daemonShutdownHandler , NULL ) < 0 )
return - 1 ;
2011-08-15 15:40:46 +08:00
if ( virNetServerAddSignalHandler ( srv , SIGHUP , daemonReloadHandler , NULL ) < 0 )
return - 1 ;
2011-05-16 18:13:11 +01:00
return 0 ;
}
2009-10-16 11:48:50 +01:00
2011-05-16 18:13:11 +01:00
static void daemonRunStateInit ( void * opaque )
{
virNetServerPtr srv = opaque ;
2009-10-16 11:48:50 +01:00
2011-05-16 18:13:11 +01:00
/* Start the stateful HV drivers
2011-08-23 11:02:02 -06:00
* This is deliberately done after telling the parent process
2011-05-16 18:13:11 +01:00
* 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 " ) ) ;
2011-07-21 18:23:21 +01:00
/* Ensure the main event loop quits */
kill ( getpid ( ) , SIGTERM ) ;
2011-05-16 18:13:11 +01:00
virNetServerFree ( srv ) ;
return ;
2009-10-16 11:48:50 +01:00
}
2011-05-16 18:13:11 +01:00
/* Only now accept clients from network */
virNetServerUpdateServices ( srv , true ) ;
virNetServerFree ( srv ) ;
}
2009-10-16 11:48:50 +01:00
2011-05-16 18:13:11 +01:00
static int daemonStateInit ( virNetServerPtr srv )
{
virThread thr ;
virNetServerRef ( srv ) ;
if ( virThreadCreate ( & thr , false , daemonRunStateInit , srv ) < 0 ) {
virNetServerFree ( srv ) ;
return - 1 ;
}
2009-10-16 11:48:50 +01:00
return 0 ;
}
2007-04-04 09:32:00 +00:00
/* Print command-line usage. */
static void
2011-05-16 18:13:11 +01:00
daemonUsage ( const char * argv0 , bool privileged )
2007-04-04 09:32:00 +00:00
{
fprintf ( stderr ,
2010-05-20 10:01:32 +02:00
_ ( " \n \
2007-06-11 12:04:54 +00: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-26 23:48:46 +00:00
- l | - - listen Listen for TCP / IP connections . \ n \
- t | - - timeout < secs > Exit after timeout period . \ n \
2007-08-07 13:24:22 +00:00
- f | - - config < file > Configuration file . \ n \
2008-12-12 07:56:50 +00:00
| - - version Display version information . \ n \
2007-06-11 12:04:54 +00:00
- p | - - pid - file < file > Change name of PID file . \ n \
\ n \
2011-05-16 18:13:11 +01:00
libvirt management daemon : \ n " ), argv0);
if ( privileged ) {
fprintf ( stderr ,
_ ( " \n \
2007-06-11 12:04:54 +00:00
Default paths : \ n \
\ n \
2009-11-10 15:53:20 +01:00
Configuration file ( unless overridden by - f ) : \ n \
2010-05-20 10:01:32 +02:00
% s / libvirt / libvirtd . conf \ n \
2007-06-11 12:04:54 +00:00
\ n \
2011-05-16 18:13:11 +01:00
Sockets : \ n \
2010-05-20 10:01:32 +02:00
% s / run / libvirt / libvirt - sock \ n \
% s / run / libvirt / libvirt - sock - ro \ n \
2007-06-26 23:48:46 +00:00
\ n \
2011-05-16 18:13:11 +01: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-26 23:48:46 +00:00
$ HOME / . libvirt / libvirt - sock ( in UNIX abstract namespace ) \ n \
2007-06-11 12:04:54 +00:00
\ n \
TLS : \ n \
2011-05-16 18:13:11 +01: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 12:04:54 +00:00
\ n \
2011-05-16 18:13:11 +01:00
PID file : \ n \
$ HOME / . libvirt / libvirtd . pid \ n \
\ n " ));
}
2007-04-04 09:32:00 +00:00
}
2008-12-12 07:56:50 +00:00
enum {
OPT_VERSION = 129
} ;
2007-02-14 01:40:09 +00:00
# define MAX_LISTEN 5
int main ( int argc , char * * argv ) {
2011-05-16 18:13:11 +01:00
virNetServerPtr srv = NULL ;
char * remote_config_file = NULL ;
2009-10-16 12:14:54 +01:00
int statuswrite = - 1 ;
2007-02-23 12:48:36 +00:00
int ret = 1 ;
2011-08-05 15:11:11 +01:00
int pid_file_fd = - 1 ;
2011-05-16 18:13:11 +01: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 ;
2011-07-08 11:44:25 -06:00
bool implicit_conf = false ;
2011-07-07 15:12:26 -06:00
bool use_polkit_dbus ;
2011-08-29 10:52:23 +08:00
char * run_dir = NULL ;
mode_t old_umask ;
2007-02-14 01:40:09 +00:00
struct option opts [ ] = {
{ " verbose " , no_argument , & verbose , 1 } ,
{ " daemon " , no_argument , & godaemon , 1 } ,
2007-06-26 23:48:46 +00:00
{ " listen " , no_argument , & ipsock , 1 } ,
2007-08-07 13:24:22 +00:00
{ " config " , required_argument , NULL , ' f ' } ,
2007-04-04 09:32:00 +00:00
{ " timeout " , required_argument , NULL , ' t ' } ,
{ " pid-file " , required_argument , NULL , ' p ' } ,
2008-12-12 07:56:50 +00:00
{ " version " , no_argument , NULL , OPT_VERSION } ,
2007-04-04 09:32:00 +00:00
{ " help " , no_argument , NULL , ' ? ' } ,
2007-02-14 01:40:09 +00:00
{ 0 , 0 , 0 , 0 }
} ;
2010-11-16 12:01:37 -07:00
if ( setlocale ( LC_ALL , " " ) = = NULL | |
bindtextdomain ( PACKAGE , LOCALEDIR ) = = NULL | |
textdomain ( PACKAGE ) = = NULL | |
virInitialize ( ) < 0 ) {
2011-05-16 18:13:11 +01:00
fprintf ( stderr , _ ( " %s: initialization failed \n " ) , argv [ 0 ] ) ;
2010-11-16 12:01:37 -07:00
exit ( EXIT_FAILURE ) ;
2010-05-20 09:52:20 +02:00
}
2009-10-16 11:29:01 +01:00
2011-08-12 13:41:29 +02:00
/* initialize early logging */
virLogSetFromEnv ( ) ;
2007-02-14 01:40:09 +00:00
while ( 1 ) {
int optidx = 0 ;
int c ;
char * tmp ;
2007-08-07 13:24:22 +00:00
c = getopt_long ( argc , argv , " ldf:p:t:v " , opts , & optidx ) ;
2007-02-14 01:40:09 +00: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-26 23:48:46 +00:00
case ' l ' :
ipsock = 1 ;
2007-02-14 01:40:09 +00:00
break ;
case ' t ' :
2008-02-08 09:15:16 +00:00
if ( virStrToLong_i ( optarg , & tmp , 10 , & timeout ) ! = 0
2007-11-14 10:53:05 +00:00
| | timeout < = 0
/* Ensure that we can multiply by 1000 without overflowing. */
2011-09-19 12:16:45 +08:00
| | timeout > INT_MAX / 1000 ) {
VIR_ERROR ( _ ( " Invalid value for timeout " ) ) ;
exit ( EXIT_FAILURE ) ;
}
2007-02-14 01:40:09 +00:00
break ;
2007-02-23 12:48:36 +00:00
case ' p ' :
2011-05-16 18:13:11 +01:00
VIR_FREE ( pid_file ) ;
2011-08-12 13:41:29 +02:00
if ( ! ( pid_file = strdup ( optarg ) ) ) {
VIR_ERROR ( _ ( " Can't allocate memory " ) ) ;
2011-05-16 18:13:11 +01:00
exit ( EXIT_FAILURE ) ;
2011-08-12 13:41:29 +02:00
}
2007-06-11 12:04:54 +00:00
break ;
case ' f ' :
2011-05-16 18:13:11 +01:00
VIR_FREE ( remote_config_file ) ;
2011-08-12 13:41:29 +02:00
if ( ! ( remote_config_file = strdup ( optarg ) ) ) {
VIR_ERROR ( _ ( " Can't allocate memory " ) ) ;
2011-05-16 18:13:11 +01:00
exit ( EXIT_FAILURE ) ;
2011-08-12 13:41:29 +02:00
}
2007-02-23 12:48:36 +00:00
break ;
2008-12-12 07:56:50 +00:00
case OPT_VERSION :
2011-05-16 18:13:11 +01:00
daemonVersion ( argv [ 0 ] ) ;
2008-12-12 07:56:50 +00:00
return 0 ;
2007-02-14 01:40:09 +00:00
case ' ? ' :
2011-05-16 18:13:11 +01:00
daemonUsage ( argv [ 0 ] , privileged ) ;
2007-02-14 01:40:09 +00:00
return 2 ;
default :
2011-08-12 13:41:29 +02:00
VIR_ERROR ( _ ( " %s: internal error: unknown flag: %c " ) ,
argv [ 0 ] , c ) ;
2009-12-15 09:43:29 +01:00
exit ( EXIT_FAILURE ) ;
2007-02-14 01:40:09 +00:00
}
}
2011-08-12 13:41:29 +02:00
if ( ! ( config = daemonConfigNew ( privileged ) ) ) {
VIR_ERROR ( _ ( " Can't create initial configuration " ) ) ;
2011-05-16 18:13:11 +01:00
exit ( EXIT_FAILURE ) ;
2011-08-12 13:41:29 +02:00
}
2011-05-16 18:13:11 +01:00
/* No explicit config, so try and find a default one */
2011-07-08 11:44:25 -06:00
if ( remote_config_file = = NULL ) {
implicit_conf = true ;
if ( daemonConfigFilePath ( privileged ,
2011-08-12 13:41:29 +02:00
& remote_config_file ) < 0 ) {
VIR_ERROR ( _ ( " Can't determine config path " ) ) ;
2011-07-08 11:44:25 -06:00
exit ( EXIT_FAILURE ) ;
2011-08-12 13:41:29 +02:00
}
2011-07-08 11:44:25 -06:00
}
2011-05-16 18:13:11 +01:00
/* Read the config file if it exists*/
if ( remote_config_file & &
2011-08-12 13:41:29 +02:00
daemonConfigLoad ( config , remote_config_file , implicit_conf ) < 0 ) {
VIR_ERROR ( _ ( " Can't load config file '%s' " ) , remote_config_file ) ;
2011-05-16 18:13:11 +01:00
exit ( EXIT_FAILURE ) ;
2011-08-12 13:41:29 +02:00
}
2011-05-16 18:13:11 +01:00
if ( config - > host_uuid & &
virSetHostUUIDStr ( config - > host_uuid ) < 0 ) {
VIR_ERROR ( _ ( " invalid host UUID: %s " ) , config - > host_uuid ) ;
exit ( EXIT_FAILURE ) ;
2009-01-12 18:22:32 +00:00
}
2011-08-12 13:41:29 +02:00
if ( daemonSetupLogging ( config , privileged , verbose , godaemon ) < 0 ) {
VIR_ERROR ( _ ( " Can't initialize logging " ) ) ;
2011-05-16 18:13:11 +01:00
exit ( EXIT_FAILURE ) ;
2011-08-12 13:41:29 +02:00
}
2011-05-16 18:13:11 +01:00
2011-08-05 15:11:11 +01:00
if ( ! pid_file & &
2011-05-16 18:13:11 +01:00
daemonPidFilePath ( privileged ,
2011-08-12 13:41:29 +02:00
& pid_file ) < 0 ) {
VIR_ERROR ( _ ( " Can't determine pid file path. " ) ) ;
2011-05-16 18:13:11 +01:00
exit ( EXIT_FAILURE ) ;
2011-08-12 13:41:29 +02:00
}
2011-05-16 18:13:11 +01:00
if ( daemonUnixSocketPaths ( config ,
privileged ,
& sock_file ,
2011-08-12 13:41:29 +02:00
& sock_file_ro ) < 0 ) {
VIR_ERROR ( _ ( " Can't determine socket paths " ) ) ;
2011-05-16 18:13:11 +01:00
exit ( EXIT_FAILURE ) ;
2011-08-12 13:41:29 +02:00
}
2011-05-16 18:13:11 +01:00
2008-05-20 16:17:36 +00:00
if ( godaemon ) {
2009-02-05 16:28:03 +00:00
char ebuf [ 1024 ] ;
2010-12-13 11:18:45 +01:00
if ( chdir ( " / " ) < 0 ) {
VIR_ERROR ( _ ( " cannot change to root directory: %s " ) ,
virStrerror ( errno , ebuf , sizeof ( ebuf ) ) ) ;
2011-05-16 18:13:11 +01:00
goto cleanup ;
2010-12-13 11:18:45 +01:00
}
2011-05-16 18:13:11 +01:00
if ( ( statuswrite = daemonForkIntoBackground ( argv [ 0 ] ) ) < 0 ) {
2009-02-05 16:28:03 +00:00
VIR_ERROR ( _ ( " Failed to fork as daemon: %s " ) ,
virStrerror ( errno , ebuf , sizeof ebuf ) ) ;
2011-05-16 18:13:11 +01:00
goto cleanup ;
2008-05-20 16:17:36 +00:00
}
}
2009-01-22 17:49:41 +00:00
/* Ensure the rundir exists (on tmpfs on some systems) */
2011-05-16 18:13:11 +01:00
if ( privileged ) {
2011-08-29 10:52:23 +08:00
run_dir = strdup ( LOCALSTATEDIR " /run/libvirt " ) ;
} else {
char * user_dir = virGetUserDirectory ( geteuid ( ) ) ;
if ( ! user_dir ) {
VIR_ERROR ( _ ( " Can't determine user directory " ) ) ;
goto cleanup ;
2009-01-22 17:49:41 +00:00
}
2011-08-29 10:52:23 +08:00
ignore_value ( virAsprintf ( & run_dir , " %s/.libvirt/ " , user_dir ) ) ;
VIR_FREE ( user_dir ) ;
2009-01-22 17:49:41 +00:00
}
2011-08-29 10:52:23 +08:00
if ( ! run_dir ) {
virReportOOMError ( ) ;
goto cleanup ;
}
old_umask = umask ( 022 ) ;
if ( virFileMakePath ( run_dir ) < 0 ) {
char ebuf [ 1024 ] ;
VIR_ERROR ( _ ( " unable to create rundir %s: %s " ) , run_dir ,
virStrerror ( errno , ebuf , sizeof ( ebuf ) ) ) ;
ret = VIR_DAEMON_ERR_RUNDIR ;
goto cleanup ;
}
umask ( old_umask ) ;
2009-01-22 17:49:41 +00:00
2011-08-05 15:11:11 +01:00
/* Try to claim the pidfile, exiting if we can't */
if ( ( pid_file_fd = virPidFileAcquirePath ( pid_file , getpid ( ) ) ) < 0 ) {
ret = VIR_DAEMON_ERR_PIDFILE ;
goto cleanup ;
}
2011-07-07 15:12:26 -06:00
use_polkit_dbus = config - > auth_unix_rw = = REMOTE_AUTH_POLKIT | |
config - > auth_unix_ro = = REMOTE_AUTH_POLKIT ;
2011-05-16 18:13:11 +01:00
if ( ! ( srv = virNetServerNew ( config - > min_workers ,
config - > max_workers ,
2011-08-12 14:04:31 +02:00
config - > prio_workers ,
2011-05-16 18:13:11 +01:00
config - > max_clients ,
2011-08-24 15:33:34 +02:00
config - > keepalive_interval ,
config - > keepalive_count ,
! ! config - > keepalive_required ,
2011-05-16 18:13:11 +01:00
config - > mdns_adv ? config - > mdns_name : NULL ,
2011-07-07 15:12:26 -06:00
use_polkit_dbus ,
2011-05-16 18:13:11 +01:00
remoteClientInitHook ) ) ) {
ret = VIR_DAEMON_ERR_INIT ;
goto cleanup ;
}
2009-06-12 13:20:13 +00:00
/* Beyond this point, nothing should rely on using
* getuid / geteuid ( ) = = 0 , for privilege level checks .
*/
2011-05-16 18:13:11 +01:00
if ( daemonSetupPrivs ( ) < 0 ) {
2009-10-16 12:14:54 +01:00
ret = VIR_DAEMON_ERR_PRIVS ;
2011-05-16 18:13:11 +01:00
goto cleanup ;
2009-10-16 12:14:54 +01:00
}
2009-01-22 17:49:41 +00:00
2011-05-16 18:13:11 +01:00
daemonInitialize ( ) ;
2011-02-17 13:17:59 +00:00
2011-05-16 18:13:11 +01: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 12:14:54 +01:00
ret = VIR_DAEMON_ERR_INIT ;
2011-05-16 18:13:11 +01:00
goto cleanup ;
}
if ( virNetServerAddProgram ( srv , remoteProgram ) < 0 ) {
ret = VIR_DAEMON_ERR_INIT ;
goto cleanup ;
2007-12-05 15:34:05 +00:00
}
2007-02-16 18:28:17 +00:00
2011-05-16 18:13:11 +01: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 12:14:54 +01:00
}
2009-10-16 11:48:50 +01:00
2011-05-16 18:13:11 +01:00
if ( timeout ! = - 1 )
virNetServerAutoShutdown ( srv ,
timeout ,
daemonShutdownCheck ,
NULL ) ;
if ( ( daemonSetupSignals ( srv ) ) < 0 ) {
ret = VIR_DAEMON_ERR_SIGNAL ;
goto cleanup ;
2009-10-16 12:14:54 +01:00
}
2007-02-14 01:40:09 +00:00
2011-05-16 18:13:11 +01:00
if ( config - > audit_level ) {
2010-09-15 14:44:11 +01:00
if ( virAuditOpen ( ) < 0 ) {
2011-05-16 18:13:11 +01:00
if ( config - > audit_level > 1 ) {
2010-09-15 14:44:11 +01:00
ret = VIR_DAEMON_ERR_AUDIT ;
2011-05-16 18:13:11 +01:00
goto cleanup ;
2010-09-15 14:44:11 +01:00
}
}
}
2011-05-16 18:13:11 +01:00
virAuditLog ( config - > audit_logging ) ;
2010-09-15 14:44:11 +01:00
2010-03-26 15:53:32 +01:00
/* setup the hooks if any */
2010-03-30 15:06:13 +02:00
if ( virHookInitialize ( ) < 0 ) {
2010-03-26 15:53:32 +01:00
ret = VIR_DAEMON_ERR_HOOKS ;
2011-05-16 18:13:11 +01:00
goto cleanup ;
2010-03-26 15:53:32 +01:00
}
2009-10-19 18:28:28 +01:00
/* Disable error func, now logging is setup */
2011-05-16 18:13:11 +01:00
virSetErrorFunc ( NULL , daemonErrorHandler ) ;
2011-01-21 17:25:01 +00:00
virSetErrorLogPriorityFunc ( daemonErrorLogFilter ) ;
2009-10-19 18:28:28 +01:00
2010-03-26 15:53:32 +01: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 18:13:11 +01:00
if ( daemonSetupNetworking ( srv , config ,
sock_file , sock_file_ro ,
ipsock , privileged ) < 0 ) {
2009-10-16 12:14:54 +01:00
ret = VIR_DAEMON_ERR_NETWORK ;
2011-05-16 18:13:11 +01:00
goto cleanup ;
2007-12-05 15:34:05 +00:00
}
2009-10-16 12:14:54 +01: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 15:48:48 -05:00
VIR_FORCE_CLOSE ( statuswrite ) ;
2009-10-16 12:14:54 +01:00
}
2011-05-16 18:13:11 +01:00
/* Initialize drivers & then start accepting new clients from network */
if ( daemonStateInit ( srv ) < 0 ) {
ret = VIR_DAEMON_ERR_INIT ;
goto cleanup ;
2009-10-16 12:14:54 +01:00
}
2007-02-14 01:40:09 +00:00
2011-05-16 18:13:11 +01:00
/* Run event loop. */
virNetServerRun ( srv ) ;
2009-10-16 16:34:37 +01:00
2007-02-23 12:48:36 +00:00
ret = 0 ;
2010-03-26 15:53:32 +01:00
virHookCall ( VIR_HOOK_DRIVER_DAEMON , " - " , VIR_HOOK_DAEMON_OP_SHUTDOWN ,
0 , " shutdown " , NULL ) ;
2011-05-16 18:13:11 +01:00
cleanup :
virNetServerProgramFree ( remoteProgram ) ;
virNetServerProgramFree ( qemuProgram ) ;
2011-08-04 16:54:58 +08:00
virNetServerClose ( srv ) ;
2011-05-16 18:13:11 +01:00
virNetServerFree ( srv ) ;
2009-10-16 12:14:54 +01: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 15:48:48 -05:00
VIR_FORCE_CLOSE ( statuswrite ) ;
2009-10-16 12:14:54 +01:00
}
2011-08-05 15:11:11 +01:00
if ( pid_file_fd ! = - 1 )
virPidFileReleasePath ( pid_file , pid_file_fd ) ;
2011-05-16 18:13:11 +01:00
VIR_FREE ( sock_file ) ;
VIR_FREE ( sock_file_ro ) ;
VIR_FREE ( pid_file ) ;
VIR_FREE ( remote_config_file ) ;
2011-08-29 10:52:23 +08:00
VIR_FREE ( run_dir ) ;
2011-05-16 18:13:11 +01:00
daemonConfigFree ( config ) ;
virLogShutdown ( ) ;
2007-02-23 12:48:36 +00:00
return ret ;
2007-02-14 01:40:09 +00:00
}