2010-08-14 19:59:25 +02:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2010-02-01 03:33:24 +01:00
2010-02-03 13:03:47 +01: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 00:20:58 +02: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 13:03:47 +01: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 00:20:58 +02:00
Lesser General Public License for more details .
2010-02-03 13:03:47 +01:00
2012-04-12 00:20:58 +02:00
You should have received a copy of the GNU Lesser General Public License
2010-02-03 13:03:47 +01:00
along with systemd ; If not , see < http : //www.gnu.org/licenses/>.
* * */
2010-02-01 03:33:24 +01:00
# include <errno.h>
2011-03-30 02:12:46 +02:00
# include <unistd.h>
2010-02-01 03:33:24 +01:00
# include "log.h"
2010-05-09 23:53:52 +02:00
# include "strv.h"
2011-03-04 18:34:56 +01:00
# include "build.h"
2011-07-23 03:44:47 +02:00
# include "install.h"
2012-09-06 22:23:11 +02:00
# include "selinux-access.h"
2012-04-13 21:33:28 +02:00
# include "watchdog.h"
2014-05-22 14:21:38 +02:00
# include "clock-util.h"
2012-05-09 01:24:50 +02:00
# include "path-util.h"
2012-10-04 20:08:17 +02:00
# include "virt.h"
2014-02-25 00:50:38 +01:00
# include "architecture.h"
2013-02-11 03:46:08 +01:00
# include "env-util.h"
2013-11-19 21:12:59 +01:00
# include "dbus.h"
2014-08-06 11:34:40 +02:00
# include "dbus-job.h"
2013-11-19 21:12:59 +01:00
# include "dbus-manager.h"
# include "dbus-unit.h"
# include "dbus-snapshot.h"
# include "dbus-execute.h"
# include "bus-errors.h"
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
static int property_get_version (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( reply ) ;
return sd_bus_message_append ( reply , " s " , PACKAGE_VERSION ) ;
}
2011-03-04 19:47:43 +01:00
2013-11-19 21:12:59 +01:00
static int property_get_features (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( reply ) ;
return sd_bus_message_append ( reply , " s " , SYSTEMD_FEATURES ) ;
}
static int property_get_virtualization (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
const char * id = NULL ;
assert ( bus ) ;
assert ( reply ) ;
detect_virtualization ( & id ) ;
return sd_bus_message_append ( reply , " s " , id ) ;
}
2014-02-25 00:50:38 +01:00
static int property_get_architecture (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
assert ( bus ) ;
assert ( reply ) ;
return sd_bus_message_append ( reply , " s " , architecture_to_string ( uname_architecture ( ) ) ) ;
}
2013-11-19 21:12:59 +01:00
static int property_get_tainted (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
2013-11-21 19:34:37 +01:00
char buf [ sizeof ( " split-usr:mtab-not-symlink:cgroups-missing:local-hwclock: " ) ] = " " , * e = buf ;
2013-11-19 21:12:59 +01:00
_cleanup_free_ char * p = NULL ;
Manager * m = userdata ;
assert ( bus ) ;
assert ( reply ) ;
2011-04-16 01:54:49 +02:00
assert ( m ) ;
2011-03-04 19:47:43 +01:00
2011-03-30 00:47:50 +02:00
if ( m - > taint_usr )
2012-05-03 15:46:04 +02:00
e = stpcpy ( e , " split-usr: " ) ;
2011-03-04 19:47:43 +01:00
2011-03-30 02:12:46 +02:00
if ( readlink_malloc ( " /etc/mtab " , & p ) < 0 )
2012-05-03 15:46:04 +02:00
e = stpcpy ( e , " mtab-not-symlink: " ) ;
2011-03-04 19:47:43 +01:00
2011-03-30 02:12:46 +02:00
if ( access ( " /proc/cgroups " , F_OK ) < 0 )
2012-05-09 21:42:56 +02:00
e = stpcpy ( e , " cgroups-missing: " ) ;
2011-03-30 02:12:46 +02:00
2014-05-22 14:21:38 +02:00
if ( clock_is_localtime ( ) > 0 )
2012-05-09 21:42:56 +02:00
e = stpcpy ( e , " local-hwclock: " ) ;
2012-05-03 15:46:04 +02:00
2012-05-09 21:42:56 +02:00
/* remove the last ':' */
if ( e ! = buf )
e [ - 1 ] = 0 ;
2012-05-03 15:46:04 +02:00
2013-11-19 21:12:59 +01:00
return sd_bus_message_append ( reply , " s " , buf ) ;
2011-03-04 19:47:43 +01:00
}
2013-11-19 21:12:59 +01:00
static int property_get_log_target (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2010-04-10 17:40:18 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( reply ) ;
2010-04-10 17:40:18 +02:00
2013-11-19 21:12:59 +01:00
return sd_bus_message_append ( reply , " s " , log_target_to_string ( log_get_target ( ) ) ) ;
2010-04-10 17:40:18 +02:00
}
2013-11-19 21:12:59 +01:00
static int property_set_log_target (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * value ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
2011-03-06 17:17:02 +01:00
const char * t ;
2013-11-19 21:12:59 +01:00
int r ;
2011-03-06 17:17:02 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( value ) ;
2011-03-06 17:17:02 +01:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( value , " s " , & t ) ;
if ( r < 0 )
return r ;
2011-03-06 17:17:02 +01:00
return log_set_target_from_string ( t ) ;
}
2013-11-19 21:12:59 +01:00
static int property_get_log_level (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
2013-07-25 17:36:01 +02:00
_cleanup_free_ char * t = NULL ;
2012-10-30 14:29:38 +01:00
int r ;
2010-04-10 17:40:18 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( reply ) ;
2010-04-10 17:40:18 +02:00
2012-10-30 14:29:38 +01:00
r = log_level_to_string_alloc ( log_get_max_level ( ) , & t ) ;
if ( r < 0 )
return r ;
2010-04-10 17:40:18 +02:00
2013-11-19 21:12:59 +01:00
return sd_bus_message_append ( reply , " s " , t ) ;
2010-04-10 17:40:18 +02:00
}
2013-11-19 21:12:59 +01:00
static int property_set_log_level (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * value ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
2011-03-06 17:17:02 +01:00
const char * t ;
2013-11-19 21:12:59 +01:00
int r ;
2011-03-06 17:17:02 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( value ) ;
2011-03-06 17:17:02 +01:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( value , " s " , & t ) ;
if ( r < 0 )
return r ;
2011-03-06 17:17:02 +01:00
return log_set_max_level_from_string ( t ) ;
}
2013-11-19 21:12:59 +01:00
static int property_get_n_names (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2010-04-22 02:56:42 +02:00
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2010-04-22 02:56:42 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( reply ) ;
assert ( m ) ;
2010-04-22 02:56:42 +02:00
2013-11-19 21:12:59 +01:00
return sd_bus_message_append ( reply , " u " , ( uint32_t ) hashmap_size ( m - > units ) ) ;
2010-04-22 02:56:42 +02:00
}
2014-03-12 20:55:13 +01:00
static int property_get_n_failed_units (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
Manager * m = userdata ;
assert ( bus ) ;
assert ( reply ) ;
assert ( m ) ;
return sd_bus_message_append ( reply , " u " , ( uint32_t ) set_size ( m - > failed_units ) ) ;
}
2013-11-19 21:12:59 +01:00
static int property_get_n_jobs (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2010-04-22 02:56:42 +02:00
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2010-04-22 02:56:42 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( reply ) ;
assert ( m ) ;
2010-04-22 02:56:42 +02:00
2013-11-19 21:12:59 +01:00
return sd_bus_message_append ( reply , " u " , ( uint32_t ) hashmap_size ( m - > jobs ) ) ;
2010-04-22 02:56:42 +02:00
}
2013-11-19 21:12:59 +01:00
static int property_get_progress (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2010-09-21 04:25:48 +02:00
double d ;
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( reply ) ;
2011-04-16 01:54:49 +02:00
assert ( m ) ;
2010-09-21 04:25:48 +02:00
if ( dual_timestamp_is_set ( & m - > finish_timestamp ) )
d = 1.0 ;
else
d = 1.0 - ( ( double ) hashmap_size ( m - > jobs ) / ( double ) m - > n_installed_jobs ) ;
2013-11-19 21:12:59 +01:00
return sd_bus_message_append ( reply , " d " , d ) ;
}
2014-03-12 20:55:13 +01:00
static int property_get_system_state (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * reply ,
void * userdata ,
sd_bus_error * error ) {
Manager * m = userdata ;
assert ( bus ) ;
assert ( reply ) ;
assert ( m ) ;
return sd_bus_message_append ( reply , " s " , manager_state_to_string ( manager_state ( m ) ) ) ;
}
2013-11-19 21:12:59 +01:00
static int property_set_runtime_watchdog (
sd_bus * bus ,
const char * path ,
const char * interface ,
const char * property ,
sd_bus_message * value ,
2013-11-21 19:34:37 +01:00
void * userdata ,
sd_bus_error * error ) {
2010-09-21 04:25:48 +02:00
2013-11-19 21:12:59 +01:00
usec_t * t = userdata ;
int r ;
assert ( bus ) ;
assert ( value ) ;
assert_cc ( sizeof ( usec_t ) = = sizeof ( uint64_t ) ) ;
r = sd_bus_message_read ( value , " t " , t ) ;
if ( r < 0 )
return r ;
return watchdog_set_timeout ( t ) ;
2010-09-21 04:25:48 +02:00
}
2013-11-21 19:34:37 +01:00
static int method_get_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_free_ char * path = NULL ;
Manager * m = userdata ;
const char * name ;
Unit * u ;
int r ;
2012-10-04 20:08:17 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
2012-10-04 20:08:17 +02:00
assert ( m ) ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2012-10-04 20:08:17 +02:00
2013-11-19 21:12:59 +01:00
u = manager_get_unit ( m , name ) ;
if ( ! u )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s not loaded. " , name ) ;
2012-10-04 20:08:17 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_unit_access_check ( u , message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2012-10-04 20:08:17 +02:00
2013-11-19 21:12:59 +01:00
path = unit_dbus_path ( u ) ;
if ( ! path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2011-07-25 04:58:02 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , " o " , path ) ;
2013-11-19 21:12:59 +01:00
}
2011-07-23 03:44:47 +02:00
2013-11-21 19:34:37 +01:00
static int method_get_unit_by_pid ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_free_ char * path = NULL ;
Manager * m = userdata ;
pid_t pid ;
Unit * u ;
int r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
assert_cc ( sizeof ( pid_t ) = = sizeof ( uint32_t ) ) ;
2011-07-25 04:58:02 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " u " , & pid ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
if ( pid = = 0 ) {
2013-11-28 17:50:02 +01:00
_cleanup_bus_creds_unref_ sd_bus_creds * creds = NULL ;
r = sd_bus_query_sender_creds ( message , SD_BUS_CREDS_PID , & creds ) ;
if ( r < 0 )
return r ;
r = sd_bus_creds_get_pid ( creds , & pid ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2011-07-25 04:58:02 +02:00
}
2013-11-19 21:12:59 +01:00
u = manager_get_unit_by_pid ( m , pid ) ;
if ( ! u )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_UNIT_FOR_PID , " PID %u does not belong to any loaded unit. " , pid ) ;
2011-07-23 03:44:47 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_unit_access_check ( u , message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-11-19 21:12:59 +01:00
path = unit_dbus_path ( u ) ;
if ( ! path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2013-11-19 21:12:59 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , " o " , path ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_load_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_free_ char * path = NULL ;
Manager * m = userdata ;
const char * name ;
Unit * u ;
int r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2011-07-23 03:44:47 +02:00
2013-11-21 19:34:37 +01:00
r = manager_load_unit ( m , name , NULL , error , & u ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
2014-05-14 22:44:45 +02:00
r = selinux_unit_access_check ( u , message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
path = unit_dbus_path ( u ) ;
if ( ! path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2013-11-19 21:12:59 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , " o " , path ) ;
2011-07-23 03:44:47 +02:00
}
2013-11-21 19:34:37 +01:00
static int method_start_unit_generic ( sd_bus * bus , sd_bus_message * message , Manager * m , JobType job_type , bool reload_if_possible , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
const char * name ;
Unit * u ;
2011-07-23 03:44:47 +02:00
int r ;
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2011-07-23 03:44:47 +02:00
2013-11-21 19:34:37 +01:00
r = manager_load_unit ( m , name , NULL , error , & u ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
2013-11-21 19:34:37 +01:00
return bus_unit_method_start_generic ( bus , message , u , job_type , reload_if_possible , error ) ;
2011-07-23 03:44:47 +02:00
}
2013-11-21 19:34:37 +01:00
static int method_start_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_start_unit_generic ( bus , message , userdata , JOB_START , false , error ) ;
2013-11-19 21:12:59 +01:00
}
2012-04-13 21:33:28 +02:00
2013-11-21 19:34:37 +01:00
static int method_stop_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_start_unit_generic ( bus , message , userdata , JOB_STOP , false , error ) ;
2013-11-19 21:12:59 +01:00
}
2012-04-13 21:33:28 +02:00
2013-11-21 19:34:37 +01:00
static int method_reload_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_start_unit_generic ( bus , message , userdata , JOB_RELOAD , false , error ) ;
2013-11-19 21:12:59 +01:00
}
2012-04-13 21:33:28 +02:00
2013-11-21 19:34:37 +01:00
static int method_restart_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_start_unit_generic ( bus , message , userdata , JOB_RESTART , false , error ) ;
2012-04-13 21:33:28 +02:00
}
2013-11-21 19:34:37 +01:00
static int method_try_restart_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_start_unit_generic ( bus , message , userdata , JOB_TRY_RESTART , false , error ) ;
2013-11-19 21:12:59 +01:00
}
2012-01-16 00:23:59 +01:00
2013-11-21 19:34:37 +01:00
static int method_reload_or_restart_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_start_unit_generic ( bus , message , userdata , JOB_RESTART , true , error ) ;
2013-11-19 21:12:59 +01:00
}
2012-01-16 00:23:59 +01:00
2013-11-21 19:34:37 +01:00
static int method_reload_or_try_restart_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_start_unit_generic ( bus , message , userdata , JOB_TRY_RESTART , true , error ) ;
2013-11-19 21:12:59 +01:00
}
2012-01-16 00:23:59 +01:00
2013-11-21 19:34:37 +01:00
static int method_start_unit_replace ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
const char * old_name ;
Unit * u ;
2010-04-10 17:40:18 +02:00
int r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
2010-02-01 03:33:24 +01:00
assert ( message ) ;
assert ( m ) ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " s " , & old_name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
u = manager_get_unit ( m , old_name ) ;
if ( ! u | | ! u - > job | | u - > job - > type ! = JOB_START )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_JOB , " No job queued for unit %s " , old_name ) ;
2011-07-23 03:44:47 +02:00
2013-11-21 19:34:37 +01:00
return method_start_unit_generic ( bus , message , m , JOB_START , false , error ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-01 03:33:24 +01:00
2013-11-21 19:34:37 +01:00
static int method_kill_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
const char * name ;
Unit * u ;
int r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-08-13 02:07:22 +02:00
2013-11-19 21:12:59 +01:00
u = manager_get_unit ( m , name ) ;
if ( ! u )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s is not loaded. " , name ) ;
2011-07-13 19:56:40 +02:00
2013-11-21 19:34:37 +01:00
return bus_unit_method_kill ( bus , message , u , error ) ;
2013-11-19 21:12:59 +01:00
}
2010-10-22 16:11:50 +02:00
2013-11-21 19:34:37 +01:00
static int method_reset_failed_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
const char * name ;
Unit * u ;
int r ;
2010-10-22 16:11:50 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
u = manager_get_unit ( m , name ) ;
if ( ! u )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s is not loaded. " , name ) ;
2013-01-10 22:45:45 +01:00
2013-11-21 19:34:37 +01:00
return bus_unit_method_reset_failed ( bus , message , u , error ) ;
2013-11-19 21:12:59 +01:00
}
2013-01-10 22:45:45 +01:00
2013-11-21 19:34:37 +01:00
static int method_set_unit_properties ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
const char * name ;
Unit * u ;
int r ;
2013-01-10 22:45:45 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
u = manager_get_unit ( m , name ) ;
if ( ! u )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s is not loaded. " , name ) ;
2010-02-01 03:33:24 +01:00
2013-11-21 19:34:37 +01:00
return bus_unit_method_set_properties ( bus , message , u , error ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_start_transient_unit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
const char * name , * smode ;
Manager * m = userdata ;
JobMode mode ;
UnitType t ;
Unit * u ;
int r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " ss " , & name , & smode ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-07-18 04:58:01 +02:00
2013-11-19 21:12:59 +01:00
t = unit_name_to_type ( name ) ;
if ( t < 0 )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid unit type. " ) ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
if ( ! unit_vtable [ t ] - > can_transient )
2013-12-28 15:05:45 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Unit type %s does not support transient units. " , unit_type_to_string ( t ) ) ;
2010-07-18 04:58:01 +02:00
2013-11-19 21:12:59 +01:00
mode = job_mode_from_string ( smode ) ;
if ( mode < 0 )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Job mode %s is invalid. " , smode ) ;
2010-07-18 04:58:01 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " start " , error ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-07-18 04:58:01 +02:00
2013-11-21 20:49:04 +01:00
r = manager_load_unit ( m , name , NULL , error , & u ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2010-07-18 04:58:01 +02:00
2013-11-19 21:12:59 +01:00
if ( u - > load_state ! = UNIT_NOT_FOUND | | set_size ( u - > dependencies [ UNIT_REFERENCED_BY ] ) > 0 )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_UNIT_EXISTS , " Unit %s already exists. " , name ) ;
2010-07-18 04:58:01 +02:00
2013-11-19 21:12:59 +01:00
/* OK, the unit failed to load and is unreferenced, now let's
* fill in the transient data instead */
r = unit_make_transient ( u ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
/* Set our properties */
2013-11-21 19:34:37 +01:00
r = bus_unit_set_properties ( u , message , UNIT_RUNTIME , false , error ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
/* And load this stub fully */
r = unit_load ( u ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
manager_dispatch_load_queue ( m ) ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
/* Finally, start it */
2013-11-21 19:34:37 +01:00
return bus_unit_queue_job ( bus , message , u , JOB_START , mode , false , error ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-01 03:33:24 +01:00
2013-11-21 19:34:37 +01:00
static int method_get_job ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_free_ char * path = NULL ;
Manager * m = userdata ;
uint32_t id ;
Job * j ;
int r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " u " , & id ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
j = manager_get_job ( m , id ) ;
if ( ! j )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_JOB , " Job %u does not exist. " , ( unsigned ) id ) ;
2010-02-01 03:33:24 +01:00
2014-05-14 22:44:45 +02:00
r = selinux_unit_access_check ( j - > unit , message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
path = job_dbus_path ( j ) ;
if ( ! path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2010-02-01 03:33:24 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , " o " , path ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-01 03:33:24 +01:00
2013-11-21 19:34:37 +01:00
static int method_cancel_job ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
uint32_t id ;
Job * j ;
int r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " u " , & id ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
j = manager_get_job ( m , id ) ;
if ( ! j )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_JOB , " Job %u does not exist. " , ( unsigned ) id ) ;
2010-02-01 03:33:24 +01:00
2014-08-06 11:34:40 +02:00
return bus_job_method_cancel ( bus , message , j , error ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-05 00:38:41 +01:00
2013-11-21 19:34:37 +01:00
static int method_clear_jobs ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2013-11-21 19:34:37 +01:00
int r ;
2010-02-05 00:38:41 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-05 00:38:41 +01:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reboot " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-11-19 21:12:59 +01:00
manager_clear_jobs ( m ) ;
2010-02-05 00:38:41 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-05 00:38:41 +01:00
2013-11-21 19:34:37 +01:00
static int method_reset_failed ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2013-11-21 19:34:37 +01:00
int r ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reload " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-11-19 21:12:59 +01:00
manager_reset_failed ( m ) ;
2010-02-05 00:38:41 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-05 00:38:41 +01:00
2014-04-28 21:08:32 +02:00
static int list_units_filtered ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error , char * * states ) {
2013-11-19 21:12:59 +01:00
_cleanup_bus_message_unref_ sd_bus_message * reply = NULL ;
Manager * m = userdata ;
const char * k ;
Iterator i ;
Unit * u ;
int r ;
2010-02-05 00:38:41 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-04-10 17:37:56 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2012-10-02 23:07:00 +02:00
2013-11-21 01:51:16 +01:00
r = sd_bus_message_new_method_return ( message , & reply ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-04-10 17:37:56 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_open_container ( reply , ' a ' , " (ssssssouso) " ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-04-10 17:37:56 +02:00
2013-11-19 21:12:59 +01:00
HASHMAP_FOREACH_KEY ( u , k , m - > units , i ) {
_cleanup_free_ char * unit_path = NULL , * job_path = NULL ;
Unit * following ;
2010-04-10 17:37:56 +02:00
2013-11-19 21:12:59 +01:00
if ( k ! = u - > id )
continue ;
2010-04-10 17:37:56 +02:00
2013-11-19 21:12:59 +01:00
following = unit_following ( u ) ;
2010-04-10 17:37:56 +02:00
2014-04-28 21:08:32 +02:00
if ( ! strv_isempty ( states ) & &
! strv_contains ( states , unit_load_state_to_string ( u - > load_state ) ) & &
! strv_contains ( states , unit_active_state_to_string ( unit_active_state ( u ) ) ) & &
! strv_contains ( states , unit_sub_state_to_string ( u ) ) )
continue ;
2013-11-19 21:12:59 +01:00
unit_path = unit_dbus_path ( u ) ;
if ( ! unit_path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2013-11-19 21:12:59 +01:00
if ( u - > job ) {
job_path = job_dbus_path ( u - > job ) ;
if ( ! job_path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2010-04-10 17:37:56 +02:00
}
2013-11-19 21:12:59 +01:00
r = sd_bus_message_append (
reply , " (ssssssouso) " ,
u - > id ,
unit_description ( u ) ,
unit_load_state_to_string ( u - > load_state ) ,
unit_active_state_to_string ( unit_active_state ( u ) ) ,
unit_sub_state_to_string ( u ) ,
following ? following - > id : " " ,
unit_path ,
u - > job ? u - > job - > id : 0 ,
u - > job ? job_type_to_string ( u - > job - > type ) : " " ,
job_path ? job_path : " / " ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
}
2010-04-18 03:08:16 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
return sd_bus_send ( bus , reply , NULL ) ;
}
2010-04-18 03:08:16 +02:00
2014-04-28 21:08:32 +02:00
static int method_list_units ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return list_units_filtered ( bus , message , userdata , error , NULL ) ;
}
static int method_list_units_filtered ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
_cleanup_strv_free_ char * * states = NULL ;
int r ;
r = sd_bus_message_read_strv ( message , & states ) ;
if ( r < 0 )
return r ;
return list_units_filtered ( bus , message , userdata , error , states ) ;
}
2013-11-21 19:34:37 +01:00
static int method_list_jobs ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_bus_message_unref_ sd_bus_message * reply = NULL ;
Manager * m = userdata ;
Iterator i ;
Job * j ;
int r ;
2010-04-18 03:08:16 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-11-19 21:12:59 +01:00
2013-11-21 01:51:16 +01:00
r = sd_bus_message_new_method_return ( message , & reply ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_open_container ( reply , ' a ' , " (usssoo) " ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
HASHMAP_FOREACH ( j , m - > jobs , i ) {
_cleanup_free_ char * unit_path = NULL , * job_path = NULL ;
job_path = job_dbus_path ( j ) ;
if ( ! job_path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2013-11-19 21:12:59 +01:00
unit_path = unit_dbus_path ( j - > unit ) ;
if ( ! unit_path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_append (
reply , " (usssoo) " ,
j - > id ,
2013-11-21 21:32:23 +01:00
j - > unit - > id ,
2013-11-19 21:12:59 +01:00
job_type_to_string ( j - > type ) ,
2013-11-21 21:32:23 +01:00
job_state_to_string ( j - > state ) ,
2013-11-19 21:12:59 +01:00
job_path ,
unit_path ) ;
2012-10-02 23:07:00 +02:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
}
2013-01-10 22:45:45 +01:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-01-10 22:45:45 +01:00
2013-11-19 21:12:59 +01:00
return sd_bus_send ( bus , reply , NULL ) ;
}
2013-01-10 22:45:45 +01:00
2013-11-21 19:34:37 +01:00
static int method_subscribe ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
int r ;
2013-01-10 22:45:45 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-01 03:33:24 +01:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2012-10-02 23:07:00 +02:00
2014-03-03 01:33:45 +01:00
if ( bus = = m - > api_bus ) {
/* Note that direct bus connection subscribe by
* default , we only track peers on the API bus here */
if ( ! m - > subscribed ) {
r = sd_bus_track_new ( bus , & m - > subscribed , NULL , NULL ) ;
if ( r < 0 )
return r ;
}
r = sd_bus_track_add_sender ( m - > subscribed , message ) ;
if ( r < 0 )
return r ;
if ( r = = 0 )
return sd_bus_error_setf ( error , BUS_ERROR_ALREADY_SUBSCRIBED , " Client is already subscribed. " ) ;
}
2010-02-01 03:33:24 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-01 03:33:24 +01:00
2013-11-21 19:34:37 +01:00
static int method_unsubscribe ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
int r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-01 03:33:24 +01:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2010-02-01 03:33:24 +01:00
2014-03-03 01:33:45 +01:00
if ( bus = = m - > api_bus ) {
r = sd_bus_track_remove_sender ( m - > subscribed , message ) ;
if ( r < 0 )
return r ;
if ( r = = 0 )
return sd_bus_error_setf ( error , BUS_ERROR_NOT_SUBSCRIBED , " Client is not subscribed. " ) ;
}
2010-02-01 03:33:24 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-01 03:33:24 +01:00
2013-11-21 19:34:37 +01:00
static int method_dump ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_free_ char * dump = NULL ;
_cleanup_fclose_ FILE * f = NULL ;
Manager * m = userdata ;
size_t size ;
2013-11-21 19:34:37 +01:00
int r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-02-01 03:33:24 +01:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
f = open_memstream ( & dump , & size ) ;
if ( ! f )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
manager_dump_units ( m , f , NULL ) ;
manager_dump_jobs ( m , f , NULL ) ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
fflush ( f ) ;
2010-02-01 03:33:24 +01:00
2013-11-19 21:12:59 +01:00
if ( ferror ( f ) )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2010-04-21 03:27:44 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , " s " , dump ) ;
2013-11-19 21:12:59 +01:00
}
2012-10-02 23:07:00 +02:00
2013-11-21 19:34:37 +01:00
static int method_create_snapshot ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_free_ char * path = NULL ;
Manager * m = userdata ;
const char * name ;
int cleanup ;
2014-02-19 17:47:11 +01:00
Snapshot * s = NULL ;
2013-11-19 21:12:59 +01:00
int r ;
2010-04-21 03:27:44 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-04-21 03:27:44 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " start " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2010-04-21 03:27:44 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " sb " , & name , & cleanup ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-04-21 03:27:44 +02:00
2013-11-19 21:12:59 +01:00
if ( isempty ( name ) )
name = NULL ;
2010-04-21 03:27:44 +02:00
2013-11-21 19:34:37 +01:00
r = snapshot_create ( m , name , cleanup , error , & s ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
path = unit_dbus_path ( UNIT ( s ) ) ;
if ( ! path )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2010-04-21 03:27:44 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , " o " , path ) ;
2013-11-19 21:12:59 +01:00
}
2010-04-21 03:27:44 +02:00
2013-11-21 19:34:37 +01:00
static int method_remove_snapshot ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
const char * name ;
Unit * u ;
int r ;
2010-04-21 03:27:44 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2012-10-02 23:07:00 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " stop " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2010-04-21 03:27:44 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-04-21 03:27:44 +02:00
2013-11-19 21:12:59 +01:00
u = manager_get_unit ( m , name ) ;
if ( ! u )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s does not exist. " , name ) ;
2010-04-21 03:27:44 +02:00
2013-11-19 21:12:59 +01:00
if ( u - > type ! = UNIT_SNAPSHOT )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , BUS_ERROR_NO_SUCH_UNIT , " Unit %s is not a snapshot " , name ) ;
2010-10-14 00:53:51 +02:00
2013-11-21 19:34:37 +01:00
return bus_snapshot_method_remove ( bus , message , u , error ) ;
2013-11-19 21:12:59 +01:00
}
2012-10-02 23:07:00 +02:00
2013-11-21 19:34:37 +01:00
static int method_reload ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
int r ;
2010-10-14 00:53:51 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-10-14 00:53:51 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reload " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2010-10-14 00:53:51 +02:00
2013-11-19 21:12:59 +01:00
/* Instead of sending the reply back right away, we just
* remember that we need to and then send it after the reload
* is finished . That way the caller knows when the reload
* finished . */
2010-10-14 00:53:51 +02:00
2013-11-19 21:12:59 +01:00
assert ( ! m - > queued_message ) ;
2013-11-21 01:51:16 +01:00
r = sd_bus_message_new_method_return ( message , & m - > queued_message ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
m - > queued_message_bus = sd_bus_ref ( bus ) ;
m - > exit_code = MANAGER_RELOAD ;
2010-10-14 00:53:51 +02:00
2013-11-19 21:12:59 +01:00
return 1 ;
}
2010-10-14 00:53:51 +02:00
2013-11-21 19:34:37 +01:00
static int method_reexecute ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2013-11-21 19:34:37 +01:00
int r ;
2010-10-14 00:53:51 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-10-14 00:53:51 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reload " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
/* We don't send a reply back here, the client should
* just wait for us disconnecting . */
2010-10-14 00:53:51 +02:00
2013-11-19 21:12:59 +01:00
m - > exit_code = MANAGER_REEXECUTE ;
return 1 ;
}
2010-10-14 00:53:51 +02:00
2013-11-21 19:34:37 +01:00
static int method_exit ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2013-11-21 19:34:37 +01:00
int r ;
2010-10-14 00:53:51 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-10-14 00:53:51 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " halt " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
if ( m - > running_as = = SYSTEMD_SYSTEM )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_NOT_SUPPORTED , " Exit is only supported for user service managers. " ) ;
2010-10-14 00:53:51 +02:00
2013-11-19 21:12:59 +01:00
m - > exit_code = MANAGER_EXIT ;
2010-10-14 00:53:51 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2010-10-14 00:53:51 +02:00
2013-11-21 19:34:37 +01:00
static int method_reboot ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2013-11-21 19:34:37 +01:00
int r ;
2012-05-09 01:24:50 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2012-10-02 23:07:00 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reboot " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2012-05-09 01:24:50 +02:00
2013-11-19 21:12:59 +01:00
if ( m - > running_as ! = SYSTEMD_SYSTEM )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_NOT_SUPPORTED , " Reboot is only supported for system managers. " ) ;
2012-05-09 01:24:50 +02:00
2013-11-19 21:12:59 +01:00
m - > exit_code = MANAGER_REBOOT ;
2012-05-09 01:24:50 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2012-05-09 01:24:50 +02:00
2012-05-11 17:17:57 +02:00
2013-11-21 19:34:37 +01:00
static int method_poweroff ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2013-11-21 19:34:37 +01:00
int r ;
2012-05-11 17:17:57 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2010-05-09 23:53:52 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " halt " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2010-05-09 23:53:52 +02:00
2013-11-19 21:12:59 +01:00
if ( m - > running_as ! = SYSTEMD_SYSTEM )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_NOT_SUPPORTED , " Powering off is only supported for system managers. " ) ;
2010-05-09 23:53:52 +02:00
2013-11-19 21:12:59 +01:00
m - > exit_code = MANAGER_POWEROFF ;
2010-05-09 23:53:52 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2010-05-09 23:53:52 +02:00
2013-11-21 19:34:37 +01:00
static int method_halt ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2013-11-21 19:34:37 +01:00
int r ;
2010-05-09 23:53:52 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2011-06-15 15:31:54 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " halt " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
if ( m - > running_as ! = SYSTEMD_SYSTEM )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_NOT_SUPPORTED , " Halt is only supported for system managers. " ) ;
2011-06-15 15:31:54 +02:00
2013-11-19 21:12:59 +01:00
m - > exit_code = MANAGER_HALT ;
2011-06-15 15:31:54 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2011-06-15 15:31:54 +02:00
2013-11-21 19:34:37 +01:00
static int method_kexec ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
2013-11-21 19:34:37 +01:00
int r ;
2011-06-15 15:31:54 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2011-07-23 03:44:47 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reboot " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
if ( m - > running_as ! = SYSTEMD_SYSTEM )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_NOT_SUPPORTED , " KExec is only supported for system managers. " ) ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
m - > exit_code = MANAGER_KEXEC ;
2011-07-23 03:44:47 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2011-07-23 03:44:47 +02:00
2013-11-21 19:34:37 +01:00
static int method_switch_root ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
char * ri = NULL , * rt = NULL ;
const char * root , * init ;
Manager * m = userdata ;
int r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2011-07-23 03:44:47 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reboot " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
if ( m - > running_as ! = SYSTEMD_SYSTEM )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_NOT_SUPPORTED , " KExec is only supported for system managers. " ) ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " ss " , & root , & init ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
if ( path_equal ( root , " / " ) | | ! path_is_absolute ( root ) )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid switch root path %s " , root ) ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
/* Safety check */
if ( isempty ( init ) ) {
if ( ! path_is_os_tree ( root ) )
2014-06-13 19:45:52 +02:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Specified switch root path %s does not seem to be an OS tree. os-release file is missing. " , root ) ;
2013-11-19 21:12:59 +01:00
} else {
_cleanup_free_ char * p = NULL ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
if ( ! path_is_absolute ( init ) )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid init path %s " , init ) ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
p = strappend ( root , init ) ;
if ( ! p )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
if ( access ( p , X_OK ) < 0 )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Specified init binary %s does not exist. " , p ) ;
2013-11-19 21:12:59 +01:00
}
rt = strdup ( root ) ;
if ( ! rt )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2013-11-19 21:12:59 +01:00
if ( ! isempty ( init ) ) {
ri = strdup ( init ) ;
if ( ! ri ) {
2013-11-21 21:36:04 +01:00
free ( rt ) ;
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2011-07-23 03:44:47 +02:00
}
2013-11-19 21:12:59 +01:00
}
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
free ( m - > switch_root ) ;
m - > switch_root = rt ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
free ( m - > switch_root_init ) ;
m - > switch_root_init = ri ;
2011-07-23 03:44:47 +02:00
2013-11-21 21:36:04 +01:00
m - > exit_code = MANAGER_SWITCH_ROOT ;
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2011-07-23 03:44:47 +02:00
2013-11-21 19:34:37 +01:00
static int method_set_environment ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_strv_free_ char * * plus = NULL ;
Manager * m = userdata ;
int r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2012-10-02 23:07:00 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reload " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read_strv ( message , & plus ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
if ( ! strv_env_is_valid ( plus ) )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid environment assignments " ) ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
r = manager_environment_add ( m , NULL , plus ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2011-07-23 03:44:47 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_unset_environment ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_strv_free_ char * * minus = NULL ;
Manager * m = userdata ;
int r ;
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reload " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read_strv ( message , & minus ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
if ( ! strv_env_name_or_assignment_is_valid ( minus ) )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid environment variable names or assignments " ) ;
2013-11-19 21:12:59 +01:00
r = manager_environment_add ( m , minus , NULL ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_unset_and_set_environment ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_strv_free_ char * * minus = NULL , * * plus = NULL ;
Manager * m = userdata ;
int r ;
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " reload " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read_strv ( message , & plus ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read_strv ( message , & minus ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
if ( ! strv_env_is_valid ( plus ) )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid environment assignments " ) ;
2013-11-19 21:12:59 +01:00
if ( ! strv_env_name_or_assignment_is_valid ( minus ) )
2013-11-21 19:34:37 +01:00
return sd_bus_error_setf ( error , SD_BUS_ERROR_INVALID_ARGS , " Invalid environment variable names or assignments " ) ;
2013-11-19 21:12:59 +01:00
r = manager_environment_add ( m , minus , plus ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_list_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_bus_message_unref_ sd_bus_message * reply = NULL ;
Manager * m = userdata ;
UnitFileList * item ;
Hashmap * h ;
Iterator i ;
int r ;
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-11-19 21:12:59 +01:00
2013-11-21 01:51:16 +01:00
r = sd_bus_message_new_method_return ( message , & reply ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
h = hashmap_new ( string_hash_func , string_compare_func ) ;
if ( ! h )
2013-11-21 19:34:37 +01:00
return - ENOMEM ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
r = unit_file_get_list ( m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER , NULL , h ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
2013-11-19 21:12:59 +01:00
goto fail ;
r = sd_bus_message_open_container ( reply , ' a ' , " (ss) " ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
2013-11-19 21:12:59 +01:00
goto fail ;
HASHMAP_FOREACH ( item , h , i ) {
r = sd_bus_message_append ( reply , " (ss) " , item - > path , unit_file_state_to_string ( item - > state ) ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
2013-11-19 21:12:59 +01:00
goto fail ;
}
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
unit_file_list_free ( h ) ;
2011-07-23 03:44:47 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2011-06-15 15:31:54 +02:00
2013-11-19 21:12:59 +01:00
return sd_bus_send ( bus , reply , NULL ) ;
2013-05-28 11:05:48 +02:00
2013-11-19 21:12:59 +01:00
fail :
unit_file_list_free ( h ) ;
return r ;
}
2013-05-28 11:05:48 +02:00
2013-11-21 19:34:37 +01:00
static int method_get_unit_file_state ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
Manager * m = userdata ;
const char * name ;
UnitFileState state ;
UnitFileScope scope ;
int r ;
2013-05-28 11:05:48 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2013-06-27 21:14:56 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-06-27 21:14:56 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " s " , & name ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-06-27 21:14:56 +02:00
2013-11-19 21:12:59 +01:00
scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
2013-06-27 21:14:56 +02:00
2013-11-19 21:12:59 +01:00
state = unit_file_get_state ( scope , NULL , name ) ;
if ( state < 0 )
2013-11-21 19:34:37 +01:00
return state ;
2013-06-27 21:14:56 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , " s " , unit_file_state_to_string ( state ) ) ;
2013-11-19 21:12:59 +01:00
}
2013-06-27 21:14:56 +02:00
2013-11-21 19:34:37 +01:00
static int method_get_default_target ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_free_ char * default_target = NULL ;
Manager * m = userdata ;
UnitFileScope scope ;
int r ;
2013-06-28 04:12:58 +02:00
2013-11-19 21:12:59 +01:00
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2013-06-28 04:12:58 +02:00
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " status " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-06-28 04:12:58 +02:00
2013-11-19 21:12:59 +01:00
scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
2013-06-28 04:12:58 +02:00
2013-11-19 21:12:59 +01:00
r = unit_file_get_default ( scope , NULL , & default_target ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-06-28 04:12:58 +02:00
2013-11-21 01:51:16 +01:00
return sd_bus_reply_method_return ( message , " s " , default_target ) ;
2013-11-19 21:12:59 +01:00
}
2013-06-28 04:12:58 +02:00
2014-03-03 01:33:45 +01:00
static int send_unit_files_changed ( sd_bus * bus , void * userdata ) {
2013-11-19 21:12:59 +01:00
_cleanup_bus_message_unref_ sd_bus_message * message = NULL ;
int r ;
assert ( bus ) ;
2014-02-19 23:54:58 +01:00
r = sd_bus_message_new_signal ( bus , & message , " /org/freedesktop/systemd1 " , " org.freedesktop.systemd1.Manager " , " UnitFilesChanged " ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
return r ;
2014-03-03 01:33:45 +01:00
return sd_bus_send ( bus , message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
static int reply_unit_file_changes_and_free (
Manager * m ,
sd_bus * bus ,
sd_bus_message * message ,
int carries_install_info ,
UnitFileChange * changes ,
unsigned n_changes ) {
_cleanup_bus_message_unref_ sd_bus_message * reply = NULL ;
unsigned i ;
int r ;
2014-03-11 04:10:19 +01:00
if ( n_changes > 0 ) {
r = bus_foreach_bus ( m , NULL , send_unit_files_changed , NULL ) ;
if ( r < 0 )
log_debug ( " Failed to send UnitFilesChanged signal: %s " , strerror ( - r ) ) ;
}
2013-11-19 21:12:59 +01:00
2013-11-21 01:51:16 +01:00
r = sd_bus_message_new_method_return ( message , & reply ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
goto fail ;
if ( carries_install_info > = 0 ) {
r = sd_bus_message_append ( reply , " b " , carries_install_info ) ;
2013-06-28 04:12:58 +02:00
if ( r < 0 )
2013-11-19 21:12:59 +01:00
goto fail ;
}
r = sd_bus_message_open_container ( reply , ' a ' , " (sss) " ) ;
if ( r < 0 )
goto fail ;
2013-06-28 04:12:58 +02:00
2013-11-19 21:12:59 +01:00
for ( i = 0 ; i < n_changes ; i + + ) {
r = sd_bus_message_append (
2013-11-21 20:18:59 +01:00
reply , " (sss) " ,
2013-11-19 21:12:59 +01:00
unit_file_change_type_to_string ( changes [ i ] . type ) ,
changes [ i ] . path ,
changes [ i ] . source ) ;
2013-06-28 04:12:58 +02:00
if ( r < 0 )
2013-11-19 21:12:59 +01:00
goto fail ;
}
2013-06-28 04:12:58 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_close_container ( reply ) ;
if ( r < 0 )
goto fail ;
2013-06-28 04:12:58 +02:00
2013-11-21 20:18:59 +01:00
return sd_bus_send ( bus , reply , NULL ) ;
2013-06-28 04:12:58 +02:00
2013-11-19 21:12:59 +01:00
fail :
unit_file_changes_free ( changes , n_changes ) ;
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
}
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
static int method_enable_unit_files_generic (
sd_bus * bus ,
sd_bus_message * message ,
2014-06-16 19:49:31 +02:00
Manager * m ,
const char * verb ,
2013-11-19 21:12:59 +01:00
int ( * call ) ( UnitFileScope scope , bool runtime , const char * root_dir , char * files [ ] , bool force , UnitFileChange * * changes , unsigned * n_changes ) ,
2013-11-21 19:34:37 +01:00
bool carries_install_info ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_strv_free_ char * * l = NULL ;
2014-01-03 01:49:33 +01:00
# ifdef HAVE_SELINUX
2013-12-06 14:05:49 +01:00
char * * i ;
2014-01-03 01:49:33 +01:00
# endif
2013-11-19 21:12:59 +01:00
UnitFileChange * changes = NULL ;
unsigned n_changes = 0 ;
UnitFileScope scope ;
int runtime , force , r ;
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2012-10-02 23:07:00 +02:00
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read_strv ( message , & l ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2010-10-19 21:53:19 +02:00
2014-06-16 19:49:31 +02:00
r = sd_bus_message_read ( message , " bb " , & runtime , & force ) ;
if ( r < 0 )
return r ;
2013-12-06 14:05:49 +01:00
# ifdef HAVE_SELINUX
STRV_FOREACH ( i , l ) {
Unit * u ;
u = manager_get_unit ( m , * i ) ;
if ( u ) {
2014-05-14 22:44:45 +02:00
r = selinux_unit_access_check ( u , message , verb , error ) ;
2013-12-06 14:05:49 +01:00
if ( r < 0 )
return r ;
}
}
# endif
2013-11-19 21:12:59 +01:00
scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
2010-06-01 19:47:46 +02:00
2013-11-19 21:12:59 +01:00
r = call ( scope , runtime , NULL , l , force , & changes , & n_changes ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
return reply_unit_file_changes_and_free ( m , bus , message , carries_install_info ? r : - 1 , changes , n_changes ) ;
}
2010-06-01 19:47:46 +02:00
2013-11-21 19:34:37 +01:00
static int method_enable_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_enable_unit_files_generic ( bus , message , userdata , " enable " , unit_file_enable , true , error ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-01 03:33:24 +01:00
2013-11-21 19:34:37 +01:00
static int method_reenable_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_enable_unit_files_generic ( bus , message , userdata , " enable " , unit_file_reenable , true , error ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_link_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_enable_unit_files_generic ( bus , message , userdata , " enable " , unit_file_link , false , error ) ;
2013-11-19 21:12:59 +01:00
}
2014-06-16 19:49:31 +02:00
static int unit_file_preset_without_mode ( UnitFileScope scope , bool runtime , const char * root_dir , char * * files , bool force , UnitFileChange * * changes , unsigned * n_changes ) {
return unit_file_preset ( scope , runtime , root_dir , files , UNIT_FILE_PRESET_FULL , force , changes , n_changes ) ;
}
2013-11-21 19:34:37 +01:00
static int method_preset_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2014-06-16 19:49:31 +02:00
return method_enable_unit_files_generic ( bus , message , userdata , " enable " , unit_file_preset_without_mode , true , error ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_mask_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_enable_unit_files_generic ( bus , message , userdata , " disable " , unit_file_mask , false , error ) ;
2013-11-19 21:12:59 +01:00
}
2010-02-01 03:33:24 +01:00
2014-06-16 19:49:31 +02:00
static int method_preset_unit_files_with_mode ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
_cleanup_strv_free_ char * * l = NULL ;
# ifdef HAVE_SELINUX
char * * i ;
# endif
UnitFileChange * changes = NULL ;
unsigned n_changes = 0 ;
Manager * m = userdata ;
UnitFilePresetMode mm ;
UnitFileScope scope ;
int runtime , force , r ;
const char * mode ;
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
r = sd_bus_message_read_strv ( message , & l ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_read ( message , " sbb " , & mode , & runtime , & force ) ;
if ( r < 0 )
return r ;
if ( isempty ( mode ) )
mm = UNIT_FILE_PRESET_FULL ;
else {
mm = unit_file_preset_mode_from_string ( mode ) ;
if ( mm < 0 )
return - EINVAL ;
}
# ifdef HAVE_SELINUX
STRV_FOREACH ( i , l ) {
Unit * u ;
u = manager_get_unit ( m , * i ) ;
if ( u ) {
r = selinux_unit_access_check ( u , message , " enable " , error ) ;
if ( r < 0 )
return r ;
}
}
# endif
scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
r = unit_file_preset ( scope , runtime , NULL , l , mm , force , & changes , & n_changes ) ;
if ( r < 0 )
return r ;
return reply_unit_file_changes_and_free ( m , bus , message , r , changes , n_changes ) ;
}
2013-11-19 21:12:59 +01:00
static int method_disable_unit_files_generic (
sd_bus * bus ,
sd_bus_message * message ,
Manager * m , const
char * verb ,
2013-11-21 19:34:37 +01:00
int ( * call ) ( UnitFileScope scope , bool runtime , const char * root_dir , char * files [ ] , UnitFileChange * * changes , unsigned * n_changes ) ,
sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
_cleanup_strv_free_ char * * l = NULL ;
UnitFileChange * changes = NULL ;
unsigned n_changes = 0 ;
UnitFileScope scope ;
int r , runtime ;
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , verb , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read_strv ( message , & l ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " b " , & runtime ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
r = call ( scope , runtime , NULL , l , & changes , & n_changes ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
return reply_unit_file_changes_and_free ( m , bus , message , - 1 , changes , n_changes ) ;
}
2010-02-01 03:33:24 +01:00
2013-11-21 19:34:37 +01:00
static int method_disable_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_disable_unit_files_generic ( bus , message , userdata , " disable " , unit_file_disable , error ) ;
2010-02-01 03:33:24 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_unmask_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
return method_disable_unit_files_generic ( bus , message , userdata , " enable " , unit_file_unmask , error ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-21 19:34:37 +01:00
static int method_set_default_target ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
2013-11-19 21:12:59 +01:00
UnitFileChange * changes = NULL ;
unsigned n_changes = 0 ;
Manager * m = userdata ;
UnitFileScope scope ;
const char * name ;
int force , r ;
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
2014-05-14 22:44:45 +02:00
r = selinux_access_check ( message , " enable " , error ) ;
2013-11-21 19:34:37 +01:00
if ( r < 0 )
return r ;
2013-11-19 21:12:59 +01:00
r = sd_bus_message_read ( message , " sb " , & name , & force ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
r = unit_file_set_default ( scope , NULL , name , force , & changes , & n_changes ) ;
if ( r < 0 )
2013-11-21 19:34:37 +01:00
return r ;
2013-11-19 21:12:59 +01:00
return reply_unit_file_changes_and_free ( m , bus , message , - 1 , changes , n_changes ) ;
}
2014-06-16 19:49:31 +02:00
static int method_preset_all_unit_files ( sd_bus * bus , sd_bus_message * message , void * userdata , sd_bus_error * error ) {
UnitFileChange * changes = NULL ;
unsigned n_changes = 0 ;
Manager * m = userdata ;
UnitFilePresetMode mm ;
UnitFileScope scope ;
const char * mode ;
int force , runtime , r ;
assert ( bus ) ;
assert ( message ) ;
assert ( m ) ;
r = selinux_access_check ( message , " enable " , error ) ;
if ( r < 0 )
return r ;
r = sd_bus_message_read ( message , " sbb " , & mode , & runtime , & force ) ;
if ( r < 0 )
return r ;
if ( isempty ( mode ) )
mm = UNIT_FILE_PRESET_FULL ;
else {
mm = unit_file_preset_mode_from_string ( mode ) ;
if ( mm < 0 )
return - EINVAL ;
}
scope = m - > running_as = = SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER ;
r = unit_file_preset_all ( scope , runtime , NULL , mm , force , & changes , & n_changes ) ;
if ( r < 0 )
return r ;
return reply_unit_file_changes_and_free ( m , bus , message , - 1 , changes , n_changes ) ;
}
2013-11-19 21:12:59 +01:00
const sd_bus_vtable bus_manager_vtable [ ] = {
SD_BUS_VTABLE_START ( 0 ) ,
2013-12-22 02:24:05 +01:00
SD_BUS_PROPERTY ( " Version " , " s " , property_get_version , 0 , SD_BUS_VTABLE_PROPERTY_CONST ) ,
SD_BUS_PROPERTY ( " Features " , " s " , property_get_features , 0 , SD_BUS_VTABLE_PROPERTY_CONST ) ,
SD_BUS_PROPERTY ( " Virtualization " , " s " , property_get_virtualization , 0 , SD_BUS_VTABLE_PROPERTY_CONST ) ,
2014-02-25 00:50:38 +01:00
SD_BUS_PROPERTY ( " Architecture " , " s " , property_get_architecture , 0 , SD_BUS_VTABLE_PROPERTY_CONST ) ,
2013-12-22 02:24:05 +01:00
SD_BUS_PROPERTY ( " Tainted " , " s " , property_get_tainted , 0 , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " FirmwareTimestamp " , offsetof ( Manager , firmware_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " LoaderTimestamp " , offsetof ( Manager , loader_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " KernelTimestamp " , offsetof ( Manager , kernel_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " InitRDTimestamp " , offsetof ( Manager , initrd_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " UserspaceTimestamp " , offsetof ( Manager , userspace_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " FinishTimestamp " , offsetof ( Manager , finish_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " SecurityStartTimestamp " , offsetof ( Manager , security_start_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " SecurityFinishTimestamp " , offsetof ( Manager , security_finish_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " GeneratorsStartTimestamp " , offsetof ( Manager , generators_start_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " GeneratorsFinishTimestamp " , offsetof ( Manager , generators_finish_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " UnitsLoadStartTimestamp " , offsetof ( Manager , units_load_start_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
BUS_PROPERTY_DUAL_TIMESTAMP ( " UnitsLoadFinishTimestamp " , offsetof ( Manager , units_load_finish_timestamp ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_WRITABLE_PROPERTY ( " LogLevel " , " s " , property_get_log_level , property_set_log_level , 0 , 0 ) ,
SD_BUS_WRITABLE_PROPERTY ( " LogTarget " , " s " , property_get_log_target , property_set_log_target , 0 , 0 ) ,
SD_BUS_PROPERTY ( " NNames " , " u " , property_get_n_names , 0 , 0 ) ,
2014-03-12 20:55:13 +01:00
SD_BUS_PROPERTY ( " NFailedUnits " , " u " , property_get_n_failed_units , 0 , 0 ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_PROPERTY ( " NJobs " , " u " , property_get_n_jobs , 0 , 0 ) ,
SD_BUS_PROPERTY ( " NInstalledJobs " , " u " , bus_property_get_unsigned , offsetof ( Manager , n_installed_jobs ) , 0 ) ,
SD_BUS_PROPERTY ( " NFailedJobs " , " u " , bus_property_get_unsigned , offsetof ( Manager , n_failed_jobs ) , 0 ) ,
SD_BUS_PROPERTY ( " Progress " , " d " , property_get_progress , 0 , 0 ) ,
SD_BUS_PROPERTY ( " Environment " , " as " , NULL , offsetof ( Manager , environment ) , 0 ) ,
2013-12-22 02:24:05 +01:00
SD_BUS_PROPERTY ( " ConfirmSpawn " , " b " , bus_property_get_bool , offsetof ( Manager , confirm_spawn ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
SD_BUS_PROPERTY ( " ShowStatus " , " b " , bus_property_get_bool , offsetof ( Manager , show_status ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
SD_BUS_PROPERTY ( " UnitPath " , " as " , NULL , offsetof ( Manager , lookup_paths . unit_path ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
SD_BUS_PROPERTY ( " DefaultStandardOutput " , " s " , bus_property_get_exec_output , offsetof ( Manager , default_std_output ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
SD_BUS_PROPERTY ( " DefaultStandardError " , " s " , bus_property_get_exec_output , offsetof ( Manager , default_std_output ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
SD_BUS_WRITABLE_PROPERTY ( " RuntimeWatchdogUSec " , " t " , bus_property_get_usec , property_set_runtime_watchdog , offsetof ( Manager , runtime_watchdog ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
SD_BUS_WRITABLE_PROPERTY ( " ShutdownWatchdogUSec " , " t " , bus_property_get_usec , bus_property_set_usec , offsetof ( Manager , shutdown_watchdog ) , SD_BUS_VTABLE_PROPERTY_CONST ) ,
2014-02-24 03:20:24 +01:00
SD_BUS_PROPERTY ( " ControlGroup " , " s " , NULL , offsetof ( Manager , cgroup_root ) , 0 ) ,
2014-03-12 20:55:13 +01:00
SD_BUS_PROPERTY ( " SystemState " , " s " , property_get_system_state , 0 , 0 ) ,
2013-11-19 21:12:59 +01:00
2013-12-10 17:41:39 +01:00
SD_BUS_METHOD ( " GetUnit " , " s " , " o " , method_get_unit , SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD ( " GetUnitByPID " , " u " , " o " , method_get_unit_by_pid , SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD ( " LoadUnit " , " s " , " o " , method_load_unit , SD_BUS_VTABLE_UNPRIVILEGED ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_METHOD ( " StartUnit " , " ss " , " o " , method_start_unit , 0 ) ,
SD_BUS_METHOD ( " StartUnitReplace " , " sss " , " o " , method_start_unit_replace , 0 ) ,
SD_BUS_METHOD ( " StopUnit " , " ss " , " o " , method_stop_unit , 0 ) ,
SD_BUS_METHOD ( " ReloadUnit " , " ss " , " o " , method_reload_unit , 0 ) ,
SD_BUS_METHOD ( " RestartUnit " , " ss " , " o " , method_restart_unit , 0 ) ,
SD_BUS_METHOD ( " TryRestartUnit " , " ss " , " o " , method_try_restart_unit , 0 ) ,
SD_BUS_METHOD ( " ReloadOrRestartUnit " , " ss " , " o " , method_reload_or_restart_unit , 0 ) ,
SD_BUS_METHOD ( " ReloadOrTryRestartUnit " , " ss " , " o " , method_reload_or_try_restart_unit , 0 ) ,
2013-12-10 17:41:39 +01:00
SD_BUS_METHOD ( " KillUnit " , " ssi " , NULL , method_kill_unit , SD_BUS_VTABLE_CAPABILITY ( CAP_KILL ) ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_METHOD ( " ResetFailedUnit " , " s " , NULL , method_reset_failed_unit , 0 ) ,
2013-11-26 04:42:17 +01:00
SD_BUS_METHOD ( " SetUnitProperties " , " sba(sv) " , NULL , method_set_unit_properties , 0 ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_METHOD ( " StartTransientUnit " , " ssa(sv)a(sa(sv)) " , " o " , method_start_transient_unit , 0 ) ,
2013-12-10 17:41:39 +01:00
SD_BUS_METHOD ( " GetJob " , " u " , " o " , method_get_job , SD_BUS_VTABLE_UNPRIVILEGED ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_METHOD ( " CancelJob " , " u " , NULL , method_cancel_job , 0 ) ,
SD_BUS_METHOD ( " ClearJobs " , NULL , NULL , method_clear_jobs , 0 ) ,
SD_BUS_METHOD ( " ResetFailed " , NULL , NULL , method_reset_failed , 0 ) ,
2013-12-10 17:41:39 +01:00
SD_BUS_METHOD ( " ListUnits " , NULL , " a(ssssssouso) " , method_list_units , SD_BUS_VTABLE_UNPRIVILEGED ) ,
2014-04-28 21:08:32 +02:00
SD_BUS_METHOD ( " ListUnitsFiltered " , " as " , " a(ssssssouso) " , method_list_units_filtered , SD_BUS_VTABLE_UNPRIVILEGED ) ,
2013-12-10 17:41:39 +01:00
SD_BUS_METHOD ( " ListJobs " , NULL , " a(usssoo) " , method_list_jobs , SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD ( " Subscribe " , NULL , NULL , method_subscribe , SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD ( " Unsubscribe " , NULL , NULL , method_unsubscribe , SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD ( " Dump " , NULL , " s " , method_dump , SD_BUS_VTABLE_UNPRIVILEGED ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_METHOD ( " CreateSnapshot " , " sb " , " o " , method_create_snapshot , 0 ) ,
SD_BUS_METHOD ( " RemoveSnapshot " , " s " , NULL , method_remove_snapshot , 0 ) ,
SD_BUS_METHOD ( " Reload " , NULL , NULL , method_reload , 0 ) ,
SD_BUS_METHOD ( " Reexecute " , NULL , NULL , method_reexecute , 0 ) ,
SD_BUS_METHOD ( " Exit " , NULL , NULL , method_exit , 0 ) ,
2013-12-10 17:41:39 +01:00
SD_BUS_METHOD ( " Reboot " , NULL , NULL , method_reboot , SD_BUS_VTABLE_CAPABILITY ( CAP_SYS_BOOT ) ) ,
SD_BUS_METHOD ( " PowerOff " , NULL , NULL , method_poweroff , SD_BUS_VTABLE_CAPABILITY ( CAP_SYS_BOOT ) ) ,
SD_BUS_METHOD ( " Halt " , NULL , NULL , method_halt , SD_BUS_VTABLE_CAPABILITY ( CAP_SYS_BOOT ) ) ,
SD_BUS_METHOD ( " KExec " , NULL , NULL , method_kexec , SD_BUS_VTABLE_CAPABILITY ( CAP_SYS_BOOT ) ) ,
SD_BUS_METHOD ( " SwitchRoot " , " ss " , NULL , method_switch_root , SD_BUS_VTABLE_CAPABILITY ( CAP_SYS_BOOT ) ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_METHOD ( " SetEnvironment " , " as " , NULL , method_set_environment , 0 ) ,
SD_BUS_METHOD ( " UnsetEnvironment " , " as " , NULL , method_unset_environment , 0 ) ,
SD_BUS_METHOD ( " UnsetAndSetEnvironment " , " asas " , NULL , method_unset_and_set_environment , 0 ) ,
2013-12-10 17:41:39 +01:00
SD_BUS_METHOD ( " ListUnitFiles " , NULL , " a(ss) " , method_list_unit_files , SD_BUS_VTABLE_UNPRIVILEGED ) ,
SD_BUS_METHOD ( " GetUnitFileState " , " s " , " s " , method_get_unit_file_state , SD_BUS_VTABLE_UNPRIVILEGED ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_METHOD ( " EnableUnitFiles " , " asbb " , " ba(sss) " , method_enable_unit_files , 0 ) ,
SD_BUS_METHOD ( " DisableUnitFiles " , " asb " , " a(sss) " , method_disable_unit_files , 0 ) ,
SD_BUS_METHOD ( " ReenableUnitFiles " , " asbb " , " ba(sss) " , method_reenable_unit_files , 0 ) ,
SD_BUS_METHOD ( " LinkUnitFiles " , " asbb " , " a(sss) " , method_link_unit_files , 0 ) ,
SD_BUS_METHOD ( " PresetUnitFiles " , " asbb " , " ba(sss) " , method_preset_unit_files , 0 ) ,
2014-06-16 19:49:31 +02:00
SD_BUS_METHOD ( " PresetUnitFilesWithMode " , " assbb " , " ba(sss) " , method_preset_unit_files_with_mode , 0 ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_METHOD ( " MaskUnitFiles " , " asbb " , " a(sss) " , method_mask_unit_files , 0 ) ,
SD_BUS_METHOD ( " UnmaskUnitFiles " , " asb " , " a(sss) " , method_unmask_unit_files , 0 ) ,
SD_BUS_METHOD ( " SetDefaultTarget " , " sb " , " a(sss) " , method_set_default_target , 0 ) ,
2013-12-10 17:41:39 +01:00
SD_BUS_METHOD ( " GetDefaultTarget " , NULL , " s " , method_get_default_target , SD_BUS_VTABLE_UNPRIVILEGED ) ,
2014-06-16 19:49:31 +02:00
SD_BUS_METHOD ( " PresetAllUnitFiles " , " sbb " , " a(sss) " , method_preset_all_unit_files , 0 ) ,
2013-11-19 21:12:59 +01:00
SD_BUS_SIGNAL ( " UnitNew " , " so " , 0 ) ,
SD_BUS_SIGNAL ( " UnitRemoved " , " so " , 0 ) ,
SD_BUS_SIGNAL ( " JobNew " , " uos " , 0 ) ,
SD_BUS_SIGNAL ( " JobRemoved " , " uoss " , 0 ) ,
SD_BUS_SIGNAL ( " StartupFinished " , " tttttt " , 0 ) ,
SD_BUS_SIGNAL ( " UnitFilesChanged " , NULL , 0 ) ,
SD_BUS_SIGNAL ( " Reloading " , " b " , 0 ) ,
SD_BUS_VTABLE_END
2010-02-01 03:33:24 +01:00
} ;
2013-11-19 21:12:59 +01:00
2014-03-03 01:33:45 +01:00
static int send_finished ( sd_bus * bus , void * userdata ) {
2013-11-19 21:12:59 +01:00
_cleanup_bus_message_unref_ sd_bus_message * message = NULL ;
usec_t * times = userdata ;
int r ;
assert ( bus ) ;
assert ( times ) ;
2014-02-19 23:54:58 +01:00
r = sd_bus_message_new_signal ( bus , & message , " /org/freedesktop/systemd1 " , " org.freedesktop.systemd1.Manager " , " StartupFinished " ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
return r ;
r = sd_bus_message_append ( message , " tttttt " , times [ 0 ] , times [ 1 ] , times [ 2 ] , times [ 3 ] , times [ 4 ] , times [ 5 ] ) ;
if ( r < 0 )
return r ;
2014-03-03 01:33:45 +01:00
return sd_bus_send ( bus , message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-22 20:19:27 +01:00
void bus_manager_send_finished (
2013-11-19 21:12:59 +01:00
Manager * m ,
usec_t firmware_usec ,
usec_t loader_usec ,
usec_t kernel_usec ,
usec_t initrd_usec ,
usec_t userspace_usec ,
usec_t total_usec ) {
2013-11-22 20:19:27 +01:00
int r ;
2013-11-19 21:12:59 +01:00
assert ( m ) ;
2014-03-03 01:33:45 +01:00
r = bus_foreach_bus (
m ,
NULL ,
send_finished ,
( usec_t [ 6 ] ) {
firmware_usec ,
loader_usec ,
kernel_usec ,
initrd_usec ,
userspace_usec ,
total_usec
} ) ;
2013-11-22 20:19:27 +01:00
if ( r < 0 )
log_debug ( " Failed to send finished signal: %s " , strerror ( - r ) ) ;
2013-11-19 21:12:59 +01:00
}
2014-03-03 01:33:45 +01:00
static int send_reloading ( sd_bus * bus , void * userdata ) {
2013-11-19 21:12:59 +01:00
_cleanup_bus_message_unref_ sd_bus_message * message = NULL ;
int r ;
assert ( bus ) ;
2014-02-19 23:54:58 +01:00
r = sd_bus_message_new_signal ( bus , & message , " /org/freedesktop/systemd1 " , " org.freedesktop.systemd1.Manager " , " Reloading " ) ;
2013-11-19 21:12:59 +01:00
if ( r < 0 )
return r ;
r = sd_bus_message_append ( message , " b " , PTR_TO_INT ( userdata ) ) ;
if ( r < 0 )
return r ;
2014-03-03 01:33:45 +01:00
return sd_bus_send ( bus , message , NULL ) ;
2013-11-19 21:12:59 +01:00
}
2013-11-22 20:19:27 +01:00
void bus_manager_send_reloading ( Manager * m , bool active ) {
int r ;
2013-11-19 21:12:59 +01:00
assert ( m ) ;
2014-03-03 01:33:45 +01:00
r = bus_foreach_bus ( m , NULL , send_reloading , INT_TO_PTR ( active ) ) ;
2013-11-22 20:19:27 +01:00
if ( r < 0 )
log_debug ( " Failed to send reloading signal: %s " , strerror ( - r ) ) ;
2013-11-19 21:12:59 +01:00
}