2010-08-14 21:59:25 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2010-02-01 05:33:24 +03:00
2010-02-03 15:03:47 +03:00
/***
This file is part of systemd .
Copyright 2010 Lennart Poettering
systemd is free software ; you can redistribute it and / or modify it
2012-04-12 02:20:58 +04:00
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
2010-02-03 15:03:47 +03:00
( at your option ) any later version .
systemd 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
2012-04-12 02:20:58 +04:00
Lesser General Public License for more details .
2010-02-03 15:03:47 +03:00
2012-04-12 02:20:58 +04:00
You should have received a copy of the GNU Lesser General Public License
2010-02-03 15:03:47 +03:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
2010-02-01 05:33:24 +03:00
# include <sys/epoll.h>
# include <sys/timerfd.h>
# include <errno.h>
# include <unistd.h>
2013-11-20 00:12:59 +04:00
# include "sd-bus.h"
2010-02-01 05:33:24 +03:00
# include "log.h"
# include "strv.h"
2012-04-10 23:54:31 +04:00
# include "mkdir.h"
2012-09-17 02:21:25 +04:00
# include "missing.h"
2010-04-18 05:08:16 +04:00
# include "dbus-unit.h"
# include "dbus-job.h"
# include "dbus-manager.h"
2013-11-20 00:12:59 +04:00
# include "dbus-execute.h"
# include "dbus-kill.h"
# include "dbus-cgroup.h"
2010-09-01 05:30:59 +04:00
# include "special.h"
2013-11-20 00:12:59 +04:00
# include "dbus.h"
# include "bus-util.h"
# include "bus-error.h"
# include "bus-errors.h"
# include "strxcpyx.h"
# include "dbus-client-track.h"
2010-05-23 05:45:33 +04:00
2013-05-03 18:32:41 +04:00
# define CONNECTIONS_MAX 512
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
static void destroy_bus ( Manager * m , sd_bus * * bus ) ;
int bus_send_queued_message ( Manager * m ) {
int r ;
2010-03-31 18:29:55 +04:00
assert ( m ) ;
2010-04-08 06:58:30 +04:00
2013-11-20 00:12:59 +04:00
if ( ! m - > queued_message )
return 0 ;
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
assert ( m - > queued_message_bus ) ;
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
/* If we cannot get rid of this message we won't dispatch any
* D - Bus messages , so that we won ' t end up wanting to queue
* another message . */
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
r = sd_bus_send ( m - > queued_message_bus , m - > queued_message , NULL ) ;
if ( r < 0 )
log_warning ( " Failed to send queued message: %s " , strerror ( - r ) ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
m - > queued_message = sd_bus_message_unref ( m - > queued_message ) ;
m - > queued_message_bus = sd_bus_unref ( m - > queued_message_bus ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
return 0 ;
2010-02-01 05:33:24 +03:00
}
2013-11-21 22:34:37 +04:00
static int signal_agent_released ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-20 00:12:59 +04:00
Manager * m = userdata ;
const char * cgroup ;
int r ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( message ) ;
2010-02-01 05:33:24 +03:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
r = sd_bus_message_read ( message , " s " , & cgroup ) ;
if ( r < 0 ) {
bus_log_parse_error ( r ) ;
return 0 ;
}
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
manager_notify_cgroup_empty ( m , cgroup ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
if ( m - > running_as = = SYSTEMD_SYSTEM & & m - > system_bus ) {
/* If we are running as system manager, forward the
* message to the system bus */
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
r = sd_bus_send ( m - > system_bus , message , NULL ) ;
if ( r < 0 )
log_warning ( " Failed to forward Released message: %s " , strerror ( - r ) ) ;
}
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
return 0 ;
}
2010-02-01 05:33:24 +03:00
2013-11-21 22:34:37 +04:00
static int signal_disconnected ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-20 00:12:59 +04:00
Manager * m = userdata ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
if ( bus = = m - > api_bus )
destroy_bus ( m , & m - > api_bus ) ;
if ( bus = = m - > system_bus )
destroy_bus ( m , & m - > system_bus ) ;
if ( set_remove ( m - > private_buses , bus ) ) {
log_debug ( " Got disconnect on private connection. " ) ;
destroy_bus ( m , & bus ) ;
2010-02-01 05:33:24 +03:00
}
2013-11-20 00:12:59 +04:00
return 0 ;
2010-02-01 05:33:24 +03:00
}
2013-11-21 22:34:37 +04:00
static int signal_name_owner_changed ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-20 00:12:59 +04:00
const char * name , * old_owner , * new_owner ;
Manager * m = userdata ;
int r ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( message ) ;
2010-02-01 05:33:24 +03:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
r = sd_bus_message_read ( message , " sss " , & name , & old_owner , & new_owner ) ;
if ( r < 0 ) {
bus_log_parse_error ( r ) ;
return 0 ;
}
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
manager_dispatch_bus_name_owner_changed (
m , name ,
isempty ( old_owner ) ? NULL : old_owner ,
isempty ( new_owner ) ? NULL : new_owner ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
return 0 ;
2010-02-01 05:33:24 +03:00
}
2013-11-21 22:34:37 +04:00
static int signal_activation_request ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * ret_error ) {
2013-11-20 00:12:59 +04:00
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL ;
_cleanup_bus_message_unref_ sd_bus_message * reply = NULL ;
Manager * m = userdata ;
const char * name ;
Unit * u ;
int r ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( message ) ;
2010-02-01 05:33:24 +03:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 ) {
bus_log_parse_error ( r ) ;
return 0 ;
}
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
if ( manager_unit_inactive_or_pending ( m , SPECIAL_DBUS_SERVICE ) | |
manager_unit_inactive_or_pending ( m , SPECIAL_DBUS_SOCKET ) ) {
r = sd_bus_error_setf ( & error , BUS_ERROR_SHUTTING_DOWN , " Refusing activation, D-Bus is shutting down. " ) ;
goto failed ;
}
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
r = manager_load_unit ( m , name , NULL , & error , & u ) ;
if ( r < 0 )
goto failed ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
if ( u - > refuse_manual_start ) {
r = sd_bus_error_setf ( & error , BUS_ERROR_ONLY_BY_DEPENDENCY , " Operation refused, %u may be requested by dependency only. " , u - > id ) ;
goto failed ;
2010-02-01 05:33:24 +03:00
}
2013-11-20 00:12:59 +04:00
r = manager_add_job ( m , JOB_START , u , JOB_REPLACE , true , & error , NULL ) ;
if ( r < 0 )
goto failed ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
/* Successfully queued, that's it for us */
2010-02-01 05:33:24 +03:00
return 0 ;
2013-11-20 00:12:59 +04:00
failed :
if ( ! sd_bus_error_is_set ( & error ) )
sd_bus_error_set_errno ( & error , r ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
log_debug ( " D-Bus activation failed for %s: %s " , name , bus_error_message ( & error , r ) ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
r = sd_bus_message_new_signal ( bus , " /org/freedesktop/systemd1 " , " org.freedesktop.systemd1.Activator " , " ActivationFailure " , & reply ) ;
if ( r < 0 ) {
bus_log_create_error ( r ) ;
return 0 ;
}
2013-11-21 05:14:05 +04:00
r = sd_bus_message_append ( reply , " sss " , name , error . name , error . message ) ;
2013-11-20 00:12:59 +04:00
if ( r < 0 ) {
bus_log_create_error ( r ) ;
return 0 ;
}
r = sd_bus_send_to ( bus , reply , " org.freedesktop.DBus " , NULL ) ;
if ( r < 0 ) {
log_error ( " Failed to respond with to bus activation request: %s " , strerror ( - r ) ) ;
return r ;
}
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
return 0 ;
2010-02-01 05:33:24 +03:00
}
2013-11-20 00:12:59 +04:00
static int bus_job_find ( sd_bus * bus , const char * path , const char * interface , void * * found , void * userdata ) {
Manager * m = userdata ;
Job * j ;
int r ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( path ) ;
assert ( interface ) ;
assert ( found ) ;
2010-02-01 05:33:24 +03:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
r = manager_get_job_from_dbus_path ( m , path , & j ) ;
if ( r < 0 )
return 0 ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
* found = j ;
return 1 ;
}
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
static Unit * find_unit ( Manager * m , sd_bus * bus , const char * path ) {
Unit * u ;
int r ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
assert ( m ) ;
assert ( bus ) ;
assert ( path ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
if ( streq_ptr ( path , " /org/freedesktop/systemd1/unit/self " ) ) {
sd_bus_message * message ;
pid_t pid ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
message = sd_bus_get_current ( bus ) ;
if ( ! message )
return NULL ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
r = sd_bus_get_owner_pid ( bus , sd_bus_message_get_sender ( message ) , & pid ) ;
if ( r < 0 )
return NULL ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
u = manager_get_unit_by_pid ( m , pid ) ;
} else {
r = manager_load_unit_from_dbus_path ( m , path , NULL , & u ) ;
if ( r < 0 )
return NULL ;
}
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
return u ;
2010-02-01 05:33:24 +03:00
}
2013-11-20 00:12:59 +04:00
static int bus_unit_find ( sd_bus * bus , const char * path , const char * interface , void * * found , void * userdata ) {
Manager * m = userdata ;
Unit * u ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( path ) ;
assert ( interface ) ;
assert ( found ) ;
2010-02-01 05:33:24 +03:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
u = find_unit ( m , bus , path ) ;
if ( ! u )
return 0 ;
2011-05-23 23:36:52 +04:00
2013-11-20 00:12:59 +04:00
* found = u ;
return 1 ;
2010-02-01 05:33:24 +03:00
}
2013-11-20 00:12:59 +04:00
static int bus_unit_interface_find ( sd_bus * bus , const char * path , const char * interface , void * * found , void * userdata ) {
Manager * m = userdata ;
Unit * u ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( path ) ;
assert ( interface ) ;
assert ( found ) ;
2010-02-01 05:33:24 +03:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
u = find_unit ( m , bus , path ) ;
if ( ! u )
return 0 ;
2011-05-23 23:36:52 +04:00
2013-11-20 00:12:59 +04:00
if ( ! streq_ptr ( interface , UNIT_VTABLE ( u ) - > bus_interface ) )
return 0 ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
* found = u ;
return 1 ;
2010-02-01 05:33:24 +03:00
}
2013-11-20 00:12:59 +04:00
static int bus_unit_cgroup_find ( sd_bus * bus , const char * path , const char * interface , void * * found , void * userdata ) {
Manager * m = userdata ;
Unit * u ;
2010-02-05 02:38:41 +03:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( path ) ;
assert ( interface ) ;
assert ( found ) ;
2010-02-05 02:38:41 +03:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
u = find_unit ( m , bus , path ) ;
if ( ! u )
return 0 ;
2010-04-16 01:16:16 +04:00
2013-11-20 00:12:59 +04:00
if ( ! streq_ptr ( interface , UNIT_VTABLE ( u ) - > bus_interface ) )
return 0 ;
2010-04-16 01:16:16 +04:00
2013-11-20 00:12:59 +04:00
if ( ! unit_get_cgroup_context ( u ) )
return 0 ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
* found = u ;
return 1 ;
}
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
static int bus_cgroup_context_find ( sd_bus * bus , const char * path , const char * interface , void * * found , void * userdata ) {
Manager * m = userdata ;
CGroupContext * c ;
Unit * u ;
2010-06-07 06:15:37 +04:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( path ) ;
assert ( interface ) ;
assert ( found ) ;
assert ( m ) ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
u = find_unit ( m , bus , path ) ;
if ( ! u )
return 0 ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
if ( ! streq_ptr ( interface , UNIT_VTABLE ( u ) - > bus_interface ) )
return 0 ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
c = unit_get_cgroup_context ( u ) ;
if ( ! c )
return 0 ;
2010-02-05 02:38:41 +03:00
2013-11-20 00:12:59 +04:00
* found = c ;
return 1 ;
}
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
static int bus_exec_context_find ( sd_bus * bus , const char * path , const char * interface , void * * found , void * userdata ) {
Manager * m = userdata ;
ExecContext * c ;
Unit * u ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( path ) ;
assert ( interface ) ;
assert ( found ) ;
assert ( m ) ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
u = find_unit ( m , bus , path ) ;
if ( ! u )
return 0 ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
if ( ! streq_ptr ( interface , UNIT_VTABLE ( u ) - > bus_interface ) )
return 0 ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
c = unit_get_exec_context ( u ) ;
if ( ! c )
return 0 ;
2010-06-02 06:24:16 +04:00
2013-11-20 00:12:59 +04:00
* found = c ;
return 1 ;
2010-02-05 02:38:41 +03:00
}
2013-11-20 00:12:59 +04:00
static int bus_kill_context_find ( sd_bus * bus , const char * path , const char * interface , void * * found , void * userdata ) {
Manager * m = userdata ;
KillContext * c ;
Unit * u ;
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
assert ( path ) ;
assert ( interface ) ;
assert ( found ) ;
2010-03-31 18:29:55 +04:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
u = find_unit ( m , bus , path ) ;
if ( ! u )
return 0 ;
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
if ( ! streq_ptr ( interface , UNIT_VTABLE ( u ) - > bus_interface ) )
return 0 ;
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
c = unit_get_kill_context ( u ) ;
if ( ! c )
return 0 ;
2010-09-03 03:45:14 +04:00
2013-11-20 00:12:59 +04:00
* found = c ;
return 1 ;
}
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
static int bus_job_enumerate ( sd_bus * bus , const char * path , char * * * nodes , void * userdata ) {
_cleanup_free_ char * * l = NULL ;
Manager * m = userdata ;
unsigned k = 0 ;
Iterator i ;
Job * j ;
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
l = new0 ( char * , hashmap_size ( m - > jobs ) + 1 ) ;
if ( ! l )
return - ENOMEM ;
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
HASHMAP_FOREACH ( j , m - > jobs , i ) {
l [ k ] = job_dbus_path ( j ) ;
if ( ! l [ k ] )
return - ENOMEM ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
k + + ;
}
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
assert ( hashmap_size ( m - > jobs ) = = k ) ;
2010-08-06 05:21:50 +04:00
2013-11-20 00:12:59 +04:00
* nodes = l ;
l = NULL ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
return k ;
}
2010-09-03 03:45:14 +04:00
2013-11-20 00:12:59 +04:00
static int bus_unit_enumerate ( sd_bus * bus , const char * path , char * * * nodes , void * userdata ) {
_cleanup_free_ char * * l = NULL ;
Manager * m = userdata ;
unsigned k = 0 ;
Iterator i ;
Unit * u ;
2010-08-06 05:21:50 +04:00
2013-11-20 00:12:59 +04:00
l = new0 ( char * , hashmap_size ( m - > units ) + 1 ) ;
if ( ! l )
return - ENOMEM ;
2010-09-03 03:45:14 +04:00
2013-11-20 00:12:59 +04:00
HASHMAP_FOREACH ( u , m - > units , i ) {
l [ k ] = unit_dbus_path ( u ) ;
if ( ! l [ k ] )
return - ENOMEM ;
2010-09-03 03:45:14 +04:00
2013-11-20 00:12:59 +04:00
k + + ;
2010-08-06 05:21:50 +04:00
}
2013-11-20 00:12:59 +04:00
* nodes = l ;
l = NULL ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
return k ;
2010-06-19 05:04:04 +04:00
}
2013-11-20 00:12:59 +04:00
static int bus_setup_api_vtables ( Manager * m , sd_bus * bus ) {
UnitType t ;
int r ;
2010-06-19 05:04:04 +04:00
2010-02-01 05:33:24 +03:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
r = sd_bus_add_object_vtable ( bus , " /org/freedesktop/systemd1 " , " org.freedesktop.systemd1.Manager " , bus_manager_vtable , m ) ;
if ( r < 0 ) {
log_error ( " Failed to register Manager vtable: %s " , strerror ( - r ) ) ;
return r ;
2010-04-21 05:27:44 +04:00
}
2013-11-20 00:12:59 +04:00
r = sd_bus_add_fallback_vtable ( bus , " /org/freedesktop/systemd1/job " , " org.freedesktop.systemd1.Job " , bus_job_vtable , bus_job_find , m ) ;
if ( r < 0 ) {
log_error ( " Failed to register Job vtable: %s " , strerror ( - r ) ) ;
return r ;
2010-04-08 02:52:50 +04:00
}
2010-02-05 02:38:41 +03:00
2013-11-20 00:12:59 +04:00
r = sd_bus_add_node_enumerator ( bus , " /org/freedesktop/systemd1/job " , bus_job_enumerate , m ) ;
if ( r < 0 ) {
log_error ( " Failed to add job enumerator: %s " , strerror ( - r ) ) ;
return r ;
}
2010-04-05 00:48:47 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_add_fallback_vtable ( bus , " /org/freedesktop/systemd1/unit " , " org.freedesktop.systemd1.Unit " , bus_unit_vtable , bus_unit_find , m ) ;
if ( r < 0 ) {
log_error ( " Failed to register Unit vtable: %s " , strerror ( - r ) ) ;
return r ;
}
2010-04-05 00:48:47 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_add_node_enumerator ( bus , " /org/freedesktop/systemd1/unit " , bus_unit_enumerate , m ) ;
if ( r < 0 ) {
log_error ( " Failed to add job enumerator: %s " , strerror ( - r ) ) ;
return r ;
}
2010-04-05 00:48:47 +04:00
2013-11-20 00:12:59 +04:00
for ( t = 0 ; t < _UNIT_TYPE_MAX ; t + + ) {
r = sd_bus_add_fallback_vtable ( bus , " /org/freedesktop/systemd1/unit " , unit_vtable [ t ] - > bus_interface , unit_vtable [ t ] - > bus_vtable , bus_unit_interface_find , m ) ;
if ( r < 0 ) {
log_error ( " Failed to register type specific vtable for %s: %s " , unit_vtable [ t ] - > bus_interface , strerror ( - r ) ) ;
return r ;
}
2010-04-05 00:48:47 +04:00
2013-11-20 00:12:59 +04:00
if ( unit_vtable [ t ] - > cgroup_context_offset > 0 ) {
r = sd_bus_add_fallback_vtable ( bus , " /org/freedesktop/systemd1/unit " , unit_vtable [ t ] - > bus_interface , bus_unit_cgroup_vtable , bus_unit_cgroup_find , m ) ;
if ( r < 0 ) {
log_error ( " Failed to register control group unit vtable for %s: %s " , unit_vtable [ t ] - > bus_interface , strerror ( - r ) ) ;
return r ;
}
2010-04-05 00:48:47 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_add_fallback_vtable ( bus , " /org/freedesktop/systemd1/unit " , unit_vtable [ t ] - > bus_interface , bus_cgroup_vtable , bus_cgroup_context_find , m ) ;
if ( r < 0 ) {
log_error ( " Failed to register control group vtable for %s: %s " , unit_vtable [ t ] - > bus_interface , strerror ( - r ) ) ;
return r ;
}
2010-04-05 00:48:47 +04:00
}
2013-11-20 00:12:59 +04:00
if ( unit_vtable [ t ] - > exec_context_offset > 0 ) {
r = sd_bus_add_fallback_vtable ( bus , " /org/freedesktop/systemd1/unit " , unit_vtable [ t ] - > bus_interface , bus_exec_vtable , bus_exec_context_find , m ) ;
if ( r < 0 ) {
log_error ( " Failed to register execute vtable for %s: %s " , unit_vtable [ t ] - > bus_interface , strerror ( - r ) ) ;
return r ;
}
}
2010-04-05 00:48:47 +04:00
2013-11-20 00:12:59 +04:00
if ( unit_vtable [ t ] - > kill_context_offset > 0 ) {
r = sd_bus_add_fallback_vtable ( bus , " /org/freedesktop/systemd1/unit " , unit_vtable [ t ] - > bus_interface , bus_kill_vtable , bus_kill_context_find , m ) ;
if ( r < 0 ) {
log_error ( " Failed to register kill vtable for %s: %s " , unit_vtable [ t ] - > bus_interface , strerror ( - r ) ) ;
return r ;
}
}
2010-04-05 00:48:47 +04:00
}
2013-11-20 00:12:59 +04:00
return 0 ;
2010-04-05 00:48:47 +04:00
}
2013-11-20 00:12:59 +04:00
static int bus_setup_disconnected_match ( Manager * m , sd_bus * bus ) {
int r ;
2010-04-05 00:48:47 +04:00
2013-11-20 00:12:59 +04:00
assert ( m ) ;
assert ( bus ) ;
2010-04-05 00:48:47 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_add_match (
bus ,
" type='signal', "
" path='/org/freedesktop/DBus/Local', "
" interface='org.freedesktop.DBus.Local', "
" member='Disconnected' " ,
signal_disconnected , m ) ;
2010-04-16 01:16:16 +04:00
2013-11-20 00:12:59 +04:00
if ( r < 0 ) {
log_error ( " Failed to register match for Disconnected message: %s " , strerror ( - r ) ) ;
return r ;
2010-04-16 01:16:16 +04:00
}
2013-11-20 00:12:59 +04:00
return 0 ;
2010-02-01 05:33:24 +03:00
}
2013-11-20 00:12:59 +04:00
static int bus_on_connection ( sd_event_source * s , int fd , uint32_t revents , void * userdata ) {
_cleanup_bus_unref_ sd_bus * bus = NULL ;
_cleanup_close_ int nfd = - 1 ;
2010-06-05 00:03:22 +04:00
Manager * m = userdata ;
2013-11-20 00:12:59 +04:00
sd_id128_t id ;
int r ;
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
assert ( s ) ;
2010-06-05 00:03:22 +04:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
nfd = accept4 ( fd , NULL , NULL , SOCK_NONBLOCK | SOCK_CLOEXEC ) ;
if ( nfd < 0 ) {
log_warning ( " Failed to accept private connection, ignoring: %m " ) ;
return 0 ;
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
if ( set_size ( m - > private_buses ) > = CONNECTIONS_MAX ) {
log_warning ( " Too many concurrent connections, refusing " ) ;
return 0 ;
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = set_ensure_allocated ( & m - > private_buses , trivial_hash_func , trivial_compare_func ) ;
if ( r < 0 ) {
log_oom ( ) ;
return 0 ;
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_new ( & bus ) ;
if ( r < 0 ) {
log_warning ( " Failed to allocate new private connection bus: %s " , strerror ( - r ) ) ;
return 0 ;
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_set_fd ( bus , nfd , nfd ) ;
if ( r < 0 ) {
log_warning ( " Failed to set fd on new connection bus: %s " , strerror ( - r ) ) ;
return 0 ;
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
nfd = - 1 ;
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = bus_check_peercred ( bus ) ;
if ( r < 0 ) {
log_warning ( " Incoming private connection from unprivileged client, refusing: %s " , strerror ( - r ) ) ;
return 0 ;
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
assert_se ( sd_id128_randomize ( & id ) > = 0 ) ;
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_set_server ( bus , 1 , id ) ;
if ( r < 0 ) {
log_warning ( " Failed to enable server support for new connection bus: %s " , strerror ( - r ) ) ;
return 0 ;
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_start ( bus ) ;
if ( r < 0 ) {
log_warning ( " Failed to start new connection bus: %s " , strerror ( - r ) ) ;
return 0 ;
2010-06-05 00:03:22 +04:00
}
2013-11-20 00:12:59 +04:00
r = sd_bus_attach_event ( bus , m - > event , SD_EVENT_PRIORITY_NORMAL ) ;
if ( r < 0 ) {
log_warning ( " Failed to attach new connection bus to event loop: %s " , strerror ( - r ) ) ;
return 0 ;
2010-06-05 00:03:22 +04:00
}
2013-11-20 00:12:59 +04:00
if ( m - > running_as = = SYSTEMD_SYSTEM ) {
/* When we run as system instance we get the Released
* signal via a direct connection */
r = sd_bus_add_match (
bus ,
" type='signal', "
" interface='org.freedesktop.systemd1.Agent', "
" member='Released', "
" path='/org/freedesktop/systemd1/agent' " ,
signal_agent_released , m ) ;
if ( r < 0 ) {
log_warning ( " Failed to register Released match on new connection bus: %s " , strerror ( - r ) ) ;
return 0 ;
}
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = bus_setup_disconnected_match ( m , bus ) ;
if ( r < 0 )
return 0 ;
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = bus_setup_api_vtables ( m , bus ) ;
if ( r < 0 ) {
log_warning ( " Failed to set up API vtables on new connection bus: %s " , strerror ( - r ) ) ;
return 0 ;
}
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
r = set_put ( m - > private_buses , bus ) ;
if ( r < 0 ) {
log_warning ( " Failed to add new conenction bus to set: %s " , strerror ( - r ) ) ;
return 0 ;
2010-06-05 00:03:22 +04:00
}
2013-11-20 00:12:59 +04:00
bus = NULL ;
2010-06-05 00:03:22 +04:00
2013-11-20 00:12:59 +04:00
log_debug ( " Accepted new private connection. " ) ;
2010-06-05 00:03:22 +04:00
2010-03-31 18:29:55 +04:00
return 0 ;
}
2013-11-20 00:12:59 +04:00
static int bus_list_names ( Manager * m , sd_bus * bus ) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL ;
_cleanup_bus_message_unref_ sd_bus_message * reply = NULL ;
const char * name ;
int r ;
2010-06-19 05:04:04 +04:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
assert ( bus ) ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_call_method (
bus ,
" org.freedesktop.DBus " ,
" /org/freedesktop/DBus " ,
" org.freedesktop.DBus " ,
" ListNames " ,
& error , & reply ,
NULL ) ;
if ( r < 0 ) {
log_error ( " Failed to get initial list of names: %s " , bus_error_message ( & error , r ) ) ;
return r ;
2010-06-19 05:04:04 +04:00
}
2013-11-20 00:12:59 +04:00
r = sd_bus_message_enter_container ( reply , ' a ' , " s " ) ;
if ( r < 0 )
return bus_log_parse_error ( r ) ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
/* This is a bit hacky, we say the owner of the name is the
* name itself , because we don ' t want the extra traffic to
* figure out the real owner . */
while ( ( r = sd_bus_message_read ( reply , " s " , & name ) ) > 0 )
manager_dispatch_bus_name_owner_changed ( m , name , NULL , name ) ;
if ( r < 0 )
return bus_log_parse_error ( r ) ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_message_exit_container ( reply ) ;
if ( r < 0 )
return bus_log_parse_error ( r ) ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
return 0 ;
2010-06-19 05:04:04 +04:00
}
2013-11-20 00:12:59 +04:00
static int bus_setup_api ( Manager * m , sd_bus * bus ) {
int r ;
2010-04-06 18:32:07 +04:00
2013-11-20 00:12:59 +04:00
assert ( m ) ;
assert ( bus ) ;
2010-02-05 02:38:41 +03:00
2013-11-20 00:12:59 +04:00
r = bus_setup_api_vtables ( m , bus ) ;
if ( r < 0 )
return r ;
2011-12-18 17:58:10 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_add_match (
bus ,
" type='signal', "
" sender='org.freedesktop.DBus', "
" path='/org/freedesktop/DBus', "
" interface='org.freedesktop.DBus', "
" member='NameOwnerChanged' " ,
signal_name_owner_changed , m ) ;
if ( r < 0 )
log_warning ( " Failed to subscribe to NameOwnerChanged signal: %s " , strerror ( - r ) ) ;
r = sd_bus_add_match (
bus ,
" type='signal', "
" sender='org.freedesktop.DBus', "
" path='/org/freedesktop/DBus', "
" interface='org.freedesktop.systemd1.Activator', "
" member='ActivationRequest' " ,
signal_activation_request , m ) ;
if ( r < 0 )
log_warning ( " Failed to subscribe to activation signal: %s " , strerror ( - r ) ) ;
2011-12-18 17:58:10 +04:00
2013-11-20 00:12:59 +04:00
/* Allow replacing of our name, to ease implementation of
* reexecution , where we keep the old connection open until
* after the new connection is set up and the name installed
* to allow clients to synchronously wait for reexecution to
* finish */
r = sd_bus_request_name ( bus , " org.freedesktop.systemd1 " , SD_BUS_NAME_ALLOW_REPLACEMENT | SD_BUS_NAME_REPLACE_EXISTING ) ;
if ( r < 0 ) {
log_error ( " Failed to register name: %s " , strerror ( - r ) ) ;
return r ;
}
2010-09-03 03:45:14 +04:00
2013-11-20 00:12:59 +04:00
if ( r ! = SD_BUS_NAME_PRIMARY_OWNER ) {
log_error ( " Failed to acquire name. " ) ;
return - EEXIST ;
2010-02-01 05:33:24 +03:00
}
2013-11-20 00:12:59 +04:00
bus_list_names ( m , bus ) ;
2010-04-06 18:32:07 +04:00
2013-11-20 00:12:59 +04:00
log_debug ( " Successfully connected to API bus. " ) ;
2010-04-06 18:32:07 +04:00
return 0 ;
}
2013-11-20 00:12:59 +04:00
static int bus_init_api ( Manager * m ) {
_cleanup_bus_unref_ sd_bus * bus = NULL ;
2010-04-06 18:32:07 +04:00
int r ;
2013-11-20 00:12:59 +04:00
if ( m - > api_bus )
return 0 ;
2011-12-18 17:58:10 +04:00
2013-11-20 00:12:59 +04:00
/* The API and system bus is the same if we are running in system mode */
if ( m - > running_as = = SYSTEMD_SYSTEM & & m - > system_bus )
bus = sd_bus_ref ( m - > system_bus ) ;
else {
if ( m - > running_as = = SYSTEMD_SYSTEM )
r = sd_bus_open_system ( & bus ) ;
else
r = sd_bus_open_user ( & bus ) ;
2011-12-18 17:58:10 +04:00
2013-11-20 00:12:59 +04:00
if ( r < 0 ) {
log_debug ( " Failed to connect to API bus, retrying later... " ) ;
return 0 ;
2011-12-18 17:58:10 +04:00
}
2013-11-20 00:12:59 +04:00
r = sd_bus_attach_event ( bus , m - > event , SD_EVENT_PRIORITY_NORMAL ) ;
if ( r < 0 ) {
log_error ( " Failed to attach API bus to event loop: %s " , strerror ( - r ) ) ;
return 0 ;
2011-12-18 17:58:10 +04:00
}
2013-11-20 00:12:59 +04:00
r = bus_setup_disconnected_match ( m , bus ) ;
if ( r < 0 )
return 0 ;
2011-12-18 17:58:10 +04:00
}
2013-11-20 00:12:59 +04:00
r = bus_setup_api ( m , bus ) ;
2011-12-18 17:58:10 +04:00
if ( r < 0 ) {
2013-11-20 00:12:59 +04:00
log_error ( " Failed to set up API bus: %s " , strerror ( - r ) ) ;
return 0 ;
2011-12-18 17:58:10 +04:00
}
2013-11-20 00:12:59 +04:00
m - > api_bus = bus ;
bus = NULL ;
2011-12-18 17:58:10 +04:00
return 0 ;
}
2013-11-20 00:12:59 +04:00
static int bus_setup_system ( Manager * m , sd_bus * bus ) {
int r ;
2011-12-18 17:58:10 +04:00
2013-11-20 00:12:59 +04:00
assert ( m ) ;
assert ( bus ) ;
2011-12-18 17:58:10 +04:00
2013-11-20 00:12:59 +04:00
if ( m - > running_as = = SYSTEMD_SYSTEM )
return 0 ;
2011-12-18 17:58:10 +04:00
2013-11-20 00:12:59 +04:00
/* If we are a user instance we get the Released message via
* the system bus */
r = sd_bus_add_match (
bus ,
" type='signal', "
" interface='org.freedesktop.systemd1.Agent', "
" member='Released', "
" path='/org/freedesktop/systemd1/agent' " ,
signal_agent_released , m ) ;
2013-03-30 09:38:36 +04:00
2013-11-20 00:12:59 +04:00
if ( r < 0 )
log_warning ( " Failed to register Released match on system bus: %s " , strerror ( - r ) ) ;
log_debug ( " Successfully connected to system bus. " ) ;
return 0 ;
2011-12-18 17:58:10 +04:00
}
static int bus_init_system ( Manager * m ) {
2013-11-20 00:12:59 +04:00
_cleanup_bus_unref_ sd_bus * bus = NULL ;
2011-12-18 17:58:10 +04:00
int r ;
if ( m - > system_bus )
return 0 ;
2013-11-20 00:12:59 +04:00
/* The API and system bus is the same if we are running in system mode */
if ( m - > running_as = = SYSTEMD_SYSTEM & & m - > api_bus ) {
m - > system_bus = sd_bus_ref ( m - > api_bus ) ;
return 0 ;
2010-07-11 02:51:28 +04:00
}
2010-03-31 18:29:55 +04:00
2013-11-20 00:12:59 +04:00
r = sd_bus_open_system ( & bus ) ;
if ( r < 0 ) {
log_debug ( " Failed to connect to system bus, retrying later... " ) ;
return 0 ;
}
2011-12-18 17:58:10 +04:00
2013-11-20 00:12:59 +04:00
r = bus_setup_disconnected_match ( m , bus ) ;
2011-12-18 17:58:10 +04:00
if ( r < 0 )
return 0 ;
2013-11-20 00:12:59 +04:00
r = sd_bus_attach_event ( bus , m - > event , SD_EVENT_PRIORITY_NORMAL ) ;
if ( r < 0 ) {
log_error ( " Failed to attach system bus to event loop: %s " , strerror ( - r ) ) ;
2011-12-18 17:58:10 +04:00
return 0 ;
}
2013-11-20 00:12:59 +04:00
r = bus_setup_system ( m , bus ) ;
if ( r < 0 ) {
log_error ( " Fauiled to set up system bus: %s " , strerror ( - r ) ) ;
return 0 ;
2011-12-18 17:58:10 +04:00
}
2013-11-20 00:12:59 +04:00
m - > system_bus = bus ;
bus = NULL ;
2011-12-18 17:58:10 +04:00
return 0 ;
2010-06-19 05:04:04 +04:00
}
static int bus_init_private ( Manager * m ) {
2013-11-20 00:12:59 +04:00
_cleanup_close_ int fd = - 1 ;
union sockaddr_union sa = {
. un . sun_family = AF_UNIX
2010-06-19 05:04:04 +04:00
} ;
2013-11-20 00:12:59 +04:00
sd_event_source * s ;
socklen_t salen ;
int r ;
2010-06-19 05:04:04 +04:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
if ( m - > private_listen_fd > = 0 )
2010-06-19 05:04:04 +04:00
return 0 ;
2012-09-18 19:11:12 +04:00
if ( m - > running_as = = SYSTEMD_SYSTEM ) {
2011-07-02 00:34:37 +04:00
/* We want the private bus only when running as init */
if ( getpid ( ) ! = 1 )
return 0 ;
2013-11-20 00:12:59 +04:00
strcpy ( sa . un . sun_path , " /run/systemd/private " ) ;
salen = offsetof ( union sockaddr_union , un . sun_path ) + sizeof ( " /run/systemd/private " ) - 1 ;
2011-07-02 00:34:37 +04:00
} else {
2013-11-20 00:12:59 +04:00
size_t left = sizeof ( sa . un . sun_path ) ;
char * p = sa . un . sun_path ;
2011-07-02 00:34:37 +04:00
const char * e ;
2012-09-17 02:21:25 +04:00
e = secure_getenv ( " XDG_RUNTIME_DIR " ) ;
2013-11-20 00:12:59 +04:00
if ( ! e ) {
log_error ( " Failed to determine XDG_RUNTIME_DIR " ) ;
return - EHOSTDOWN ;
2011-07-02 00:34:37 +04:00
}
2013-11-20 00:12:59 +04:00
left = strpcpy ( & p , left , e ) ;
left = strpcpy ( & p , left , " /systemd/private " ) ;
2013-02-08 01:14:56 +04:00
2013-11-20 00:12:59 +04:00
salen = sizeof ( sa . un ) - left ;
2013-02-08 01:14:56 +04:00
2013-11-20 00:12:59 +04:00
mkdir_parents_label ( sa . un . sun_path , 0755 ) ;
2011-07-02 00:34:37 +04:00
}
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
unlink ( sa . un . sun_path ) ;
fd = socket ( AF_UNIX , SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK , 0 ) ;
if ( fd < 0 ) {
log_error ( " Failed to allocate private socket: %m " ) ;
return - errno ;
2010-06-19 05:04:04 +04:00
}
2013-11-20 00:12:59 +04:00
r = bind ( fd , & sa . sa , salen ) ;
if ( r < 0 ) {
log_error ( " Failed to bind private socket: %m " ) ;
return - errno ;
2010-06-19 05:04:04 +04:00
}
2013-11-20 00:12:59 +04:00
r = listen ( fd , SOMAXCONN ) ;
if ( r < 0 ) {
log_error ( " Failed to make private socket listening: %m " ) ;
return - errno ;
}
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
r = sd_event_add_io ( m - > event , fd , EPOLLIN , bus_on_connection , m , & s ) ;
if ( r < 0 ) {
log_error ( " Failed to allocate event source: %s " , strerror ( - r ) ) ;
return r ;
}
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
m - > private_listen_fd = fd ;
m - > private_listen_event_source = s ;
fd = - 1 ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
log_debug ( " Successfully created private D-Bus server. " ) ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
return 0 ;
2010-06-19 05:04:04 +04:00
}
2011-01-20 21:43:38 +03:00
int bus_init ( Manager * m , bool try_bus_connect ) {
2010-06-19 05:04:04 +04:00
int r ;
2011-01-20 21:43:38 +03:00
if ( try_bus_connect ) {
2013-11-20 00:12:59 +04:00
r = bus_init_system ( m ) ;
if ( r < 0 )
return r ;
r = bus_init_api ( m ) ;
if ( r < 0 )
2011-01-20 21:43:38 +03:00
return r ;
}
2013-07-10 21:24:03 +04:00
r = bus_init_private ( m ) ;
if ( r < 0 )
2010-06-19 05:04:04 +04:00
return r ;
2010-04-06 18:32:07 +04:00
2010-02-01 05:33:24 +03:00
return 0 ;
}
2013-11-20 00:12:59 +04:00
static void destroy_bus ( Manager * m , sd_bus * * bus ) {
2010-07-05 02:58:07 +04:00
Iterator i ;
2013-11-20 00:12:59 +04:00
Job * j ;
2010-07-05 02:58:07 +04:00
2013-11-20 00:12:59 +04:00
assert ( m ) ;
assert ( bus ) ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
if ( ! * bus )
2011-12-18 17:58:10 +04:00
return ;
2010-04-06 18:32:07 +04:00
2013-11-20 00:12:59 +04:00
/* Get rid of tracked clients on this bus */
bus_client_untrack_bus ( m - > subscribed , * bus ) ;
HASHMAP_FOREACH ( j , m - > jobs , i )
bus_client_untrack_bus ( j - > subscribed , * bus ) ;
2010-02-05 02:38:41 +03:00
2013-11-20 00:12:59 +04:00
/* Get rid of queued message on this bus */
if ( m - > queued_message_bus = = * bus ) {
m - > queued_message_bus = sd_bus_unref ( m - > queued_message_bus ) ;
2010-04-16 01:16:16 +04:00
2013-11-20 00:12:59 +04:00
if ( m - > queued_message )
m - > queued_message = sd_bus_message_unref ( m - > queued_message ) ;
2011-12-18 17:58:10 +04:00
}
2010-04-06 18:32:07 +04:00
2013-11-20 00:12:59 +04:00
/* Possibly flush unwritten data, but only if we are
* unprivileged , since we don ' t want to sync here */
if ( m - > running_as ! = SYSTEMD_SYSTEM )
sd_bus_flush ( * bus ) ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
/* And destroy the object */
sd_bus_close ( * bus ) ;
* bus = sd_bus_unref ( * bus ) ;
2010-06-19 05:04:04 +04:00
}
void bus_done ( Manager * m ) {
2013-11-20 00:12:59 +04:00
sd_bus * b ;
2010-04-16 01:16:16 +04:00
assert ( m ) ;
2013-11-20 00:12:59 +04:00
if ( m - > api_bus )
destroy_bus ( m , & m - > api_bus ) ;
if ( m - > system_bus )
destroy_bus ( m , & m - > system_bus ) ;
while ( ( b = set_steal_first ( m - > private_buses ) ) )
destroy_bus ( m , & b ) ;
2010-04-16 01:16:16 +04:00
2013-11-20 00:12:59 +04:00
set_free ( m - > private_buses ) ;
set_free ( m - > subscribed ) ;
2010-04-16 01:16:16 +04:00
2013-11-20 00:12:59 +04:00
if ( m - > private_listen_event_source )
m - > private_listen_event_source = sd_event_source_unref ( m - > private_listen_event_source ) ;
2010-04-16 01:16:16 +04:00
2013-11-20 00:12:59 +04:00
if ( m - > private_listen_fd > = 0 ) {
close_nointr_nofail ( m - > private_listen_fd ) ;
m - > private_listen_fd = - 1 ;
2010-04-16 01:16:16 +04:00
}
2010-07-05 02:58:07 +04:00
}
2011-04-29 00:07:01 +04:00
int bus_fdset_add_all ( Manager * m , FDSet * fds ) {
Iterator i ;
2013-11-20 00:12:59 +04:00
sd_bus * b ;
int fd ;
2011-04-29 00:07:01 +04:00
assert ( m ) ;
assert ( fds ) ;
/* When we are about to reexecute we add all D-Bus fds to the
* set to pass over to the newly executed systemd . They won ' t
2013-11-20 00:12:59 +04:00
* be used there however , except thatt they are closed at the
2011-04-29 00:07:01 +04:00
* very end of deserialization , those making it possible for
2011-04-29 01:51:24 +04:00
* clients to synchronously wait for systemd to reexec by
2011-04-29 00:07:01 +04:00
* simply waiting for disconnection */
2013-11-20 00:12:59 +04:00
if ( m - > api_bus ) {
fd = sd_bus_get_fd ( m - > api_bus ) ;
if ( fd > = 0 ) {
2011-04-29 00:07:01 +04:00
fd = fdset_put_dup ( fds , fd ) ;
if ( fd < 0 )
return fd ;
}
}
2013-11-20 00:12:59 +04:00
SET_FOREACH ( b , m - > private_buses , i ) {
fd = sd_bus_get_fd ( b ) ;
if ( fd > = 0 ) {
2011-04-29 00:07:01 +04:00
fd = fdset_put_dup ( fds , fd ) ;
if ( fd < 0 )
return fd ;
}
}
2013-11-20 00:12:59 +04:00
/* We don't offer any APIs on the system bus (well, unless it
* is the same as the API bus ) hence we don ' t bother with it
* here */
2013-07-10 21:24:03 +04:00
2013-11-20 00:12:59 +04:00
return 0 ;
2013-07-10 21:24:03 +04:00
}
void bus_serialize ( Manager * m , FILE * f ) {
assert ( m ) ;
assert ( f ) ;
2013-11-20 00:12:59 +04:00
bus_client_track_serialize ( m , f , m - > subscribed ) ;
2013-07-10 21:24:03 +04:00
}
int bus_deserialize_item ( Manager * m , const char * line ) {
assert ( m ) ;
assert ( line ) ;
2013-11-20 00:12:59 +04:00
return bus_client_track_deserialize_item ( m , & m - > subscribed , line ) ;
2013-07-10 21:24:03 +04:00
}