2010-08-17 05:33:07 +04:00
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2009-11-18 02:42:52 +03:00
2012-07-18 21:07:51 +04:00
# pragma once
2009-11-18 02:42:52 +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/>.
* * */
2009-11-18 02:42:52 +03:00
# include <stdbool.h>
# include <inttypes.h>
2010-01-19 02:22:34 +03:00
# include <stdio.h>
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
# include "sd-bus.h"
# include "sd-event.h"
2010-04-21 05:27:44 +04:00
# include "fdset.h"
2013-06-27 06:14:27 +04:00
# include "cgroup-util.h"
2010-04-21 05:27:44 +04:00
2010-04-22 04:56:42 +04:00
/* Enforce upper limit how many names we allow */
2010-11-25 01:36:40 +03:00
# define MANAGER_MAX_NAMES 131072 /* 128K */
2010-04-22 04:56:42 +04:00
2014-08-22 18:36:38 +04:00
# define DEFAULT_MANAGER_START_TIMEOUT_USEC (15*USEC_PER_MINUTE)
2009-11-18 02:42:52 +03:00
typedef struct Manager Manager ;
2010-01-27 06:31:52 +03:00
2014-03-12 23:55:13 +04:00
typedef enum ManagerState {
2014-08-22 20:07:18 +04:00
MANAGER_INITIALIZING ,
2014-03-12 23:55:13 +04:00
MANAGER_STARTING ,
2010-04-21 05:27:44 +04:00
MANAGER_RUNNING ,
2014-03-12 23:55:13 +04:00
MANAGER_DEGRADED ,
MANAGER_MAINTENANCE ,
MANAGER_STOPPING ,
_MANAGER_STATE_MAX ,
_MANAGER_STATE_INVALID = - 1
} ManagerState ;
typedef enum ManagerExitCode {
MANAGER_OK ,
2010-04-21 05:27:44 +04:00
MANAGER_EXIT ,
MANAGER_RELOAD ,
MANAGER_REEXECUTE ,
2010-10-14 02:52:26 +04:00
MANAGER_REBOOT ,
MANAGER_POWEROFF ,
MANAGER_HALT ,
MANAGER_KEXEC ,
2012-05-09 03:24:50 +04:00
MANAGER_SWITCH_ROOT ,
2010-04-21 05:27:44 +04:00
_MANAGER_EXIT_CODE_MAX ,
_MANAGER_EXIT_CODE_INVALID = - 1
} ManagerExitCode ;
2010-01-26 23:39:06 +03:00
# include "unit.h"
2009-11-18 02:42:52 +03:00
# include "job.h"
# include "hashmap.h"
# include "list.h"
# include "set.h"
2010-06-15 16:45:15 +04:00
# include "path-lookup.h"
2013-03-14 21:12:27 +04:00
# include "execute.h"
2013-06-27 06:14:27 +04:00
# include "unit-name.h"
2014-01-28 07:27:07 +04:00
# include "exit-status.h"
2014-03-04 00:23:12 +04:00
# include "show-status.h"
2014-08-22 18:36:38 +04:00
# include "failure-action.h"
2009-11-18 02:42:52 +03:00
struct Manager {
2010-01-26 23:39:06 +03:00
/* Note that the set of units we know of is allowed to be
2011-02-21 17:32:17 +03:00
* inconsistent . However the subset of it that is loaded may
2010-01-19 01:50:13 +03:00
* not , and the list of jobs may neither . */
2010-01-26 23:39:06 +03:00
/* Active jobs and units */
Hashmap * units ; /* name string => Unit object n:1 */
2009-11-18 02:42:52 +03:00
Hashmap * jobs ; /* job id => Job object 1:1 */
2010-01-29 08:04:08 +03:00
/* To make it easy to iterate through the units of a specific
* type we maintain a per type linked list */
2012-01-15 15:04:08 +04:00
LIST_HEAD ( Unit , units_by_type [ _UNIT_TYPE_MAX ] ) ;
2010-01-29 08:04:08 +03:00
2010-01-26 23:39:06 +03:00
/* Units that need to be loaded */
2012-01-15 15:04:08 +04:00
LIST_HEAD ( Unit , load_queue ) ; /* this is actually more a stack than a queue, but uh. */
2009-11-18 02:42:52 +03:00
2010-01-26 06:18:44 +03:00
/* Jobs that need to be run */
LIST_HEAD ( Job , run_queue ) ; /* more a stack than a queue, too */
2010-02-05 02:38:41 +03:00
/* Units and jobs that have not yet been announced via
* D - Bus . When something about a job changes it is added here
* if it is not in there yet . This allows easy coalescing of
* D - Bus change signals . */
2012-01-15 15:04:08 +04:00
LIST_HEAD ( Unit , dbus_unit_queue ) ;
2010-02-05 02:38:41 +03:00
LIST_HEAD ( Job , dbus_job_queue ) ;
2010-04-21 08:01:13 +04:00
/* Units to remove */
2012-01-15 15:04:08 +04:00
LIST_HEAD ( Unit , cleanup_queue ) ;
2010-04-06 04:43:58 +04:00
2010-04-21 08:01:13 +04:00
/* Units to check when doing GC */
2012-01-15 15:04:08 +04:00
LIST_HEAD ( Unit , gc_queue ) ;
2010-04-21 08:01:13 +04:00
2013-06-27 06:14:27 +04:00
/* Units that should be realized */
LIST_HEAD ( Unit , cgroup_queue ) ;
2013-11-20 00:12:59 +04:00
sd_event * event ;
2014-02-07 14:58:25 +04:00
/* We use two hash tables here, since the same PID might be
* watched by two different units : once the unit that forked
* it off , and possibly a different unit to which it was
* joined as cgroup member . Since we know that it is either
* one or two units for each PID we just use to hashmaps
* here . */
Hashmap * watch_pids1 ; /* pid => Unit object n:1 */
Hashmap * watch_pids2 ; /* pid => Unit object n:1 */
2010-01-24 02:39:29 +03:00
2014-05-15 19:09:34 +04:00
/* A set contains all units which cgroup should be refreshed after startup */
Set * startup_units ;
2014-03-12 23:55:13 +04:00
/* A set which contains all currently failed units */
Set * failed_units ;
2013-11-25 18:22:41 +04:00
sd_event_source * run_queue_event_source ;
2010-06-19 01:12:48 +04:00
char * notify_socket ;
2013-11-20 00:12:59 +04:00
int notify_fd ;
sd_event_source * notify_event_source ;
int signal_fd ;
sd_event_source * signal_event_source ;
2010-06-19 01:12:48 +04:00
2013-11-20 00:12:59 +04:00
int time_change_fd ;
sd_event_source * time_change_event_source ;
2010-04-21 06:01:24 +04:00
2013-11-20 00:12:59 +04:00
sd_event_source * jobs_in_progress_event_source ;
2010-01-27 06:31:52 +03:00
2010-04-21 06:01:24 +04:00
unsigned n_snapshots ;
2010-01-28 04:01:15 +03:00
2010-06-15 16:45:15 +04:00
LookupPaths lookup_paths ;
2010-07-11 02:52:00 +04:00
Set * unit_path_cache ;
2010-02-13 03:07:02 +03:00
2010-05-10 01:53:52 +04:00
char * * environment ;
2012-04-06 00:08:10 +04:00
usec_t runtime_watchdog ;
usec_t shutdown_watchdog ;
2012-09-13 20:54:32 +04:00
dual_timestamp firmware_timestamp ;
dual_timestamp loader_timestamp ;
dual_timestamp kernel_timestamp ;
2010-11-08 08:31:09 +03:00
dual_timestamp initrd_timestamp ;
2012-09-13 20:54:32 +04:00
dual_timestamp userspace_timestamp ;
2010-09-21 06:14:38 +04:00
dual_timestamp finish_timestamp ;
2014-08-22 18:36:38 +04:00
2013-11-11 02:21:15 +04:00
dual_timestamp security_start_timestamp ;
dual_timestamp security_finish_timestamp ;
2013-05-08 16:29:12 +04:00
dual_timestamp generators_start_timestamp ;
dual_timestamp generators_finish_timestamp ;
2013-11-20 00:12:59 +04:00
dual_timestamp units_load_start_timestamp ;
dual_timestamp units_load_finish_timestamp ;
2010-04-17 01:24:39 +04:00
2010-11-11 23:28:33 +03:00
char * generator_unit_path ;
2012-05-23 05:43:29 +04:00
char * generator_unit_path_early ;
char * generator_unit_path_late ;
2010-08-30 23:31:40 +04:00
2010-01-28 08:46:33 +03:00
struct udev * udev ;
2013-11-26 00:08:39 +04:00
/* Data specific to the device subsystem */
2010-01-29 08:45:59 +03:00
struct udev_monitor * udev_monitor ;
2013-11-20 00:12:59 +04:00
sd_event_source * udev_event_source ;
2010-07-20 22:33:19 +04:00
Hashmap * devices_by_sysfs ;
2010-01-29 08:04:08 +03:00
/* Data specific to the mount subsystem */
FILE * proc_self_mountinfo ;
2013-11-20 00:12:59 +04:00
sd_event_source * mount_event_source ;
2010-02-01 05:33:24 +03:00
2010-05-09 20:44:11 +04:00
/* Data specific to the swap filesystem */
FILE * proc_swaps ;
2013-11-20 00:12:59 +04:00
sd_event_source * swap_event_source ;
2013-11-26 00:08:39 +04:00
Hashmap * swaps_by_devnode ;
2010-05-09 20:44:11 +04:00
2010-02-01 05:33:24 +03:00
/* Data specific to the D-Bus subsystem */
2013-11-20 00:12:59 +04:00
sd_bus * api_bus , * system_bus ;
Set * private_buses ;
int private_listen_fd ;
sd_event_source * private_listen_event_source ;
2014-03-03 04:33:45 +04:00
/* Contains all the clients that are subscribed to signals via
the API bus . Note that private bus connections are always
considered subscribes , since they last for very short only ,
and it is much simpler that way . */
sd_bus_track * subscribed ;
char * * deserialized_subscribed ;
2010-06-19 05:04:04 +04:00
2013-11-20 00:12:59 +04:00
sd_bus_message * queued_message ; /* This is used during reloading:
2010-04-21 05:27:44 +04:00
* before the reload we queue the
* reply message here , and
* afterwards we send it */
2013-11-20 00:12:59 +04:00
sd_bus * queued_message_bus ; /* The connection to send the queued message on */
2010-03-31 18:29:55 +04:00
2010-04-16 01:16:16 +04:00
Hashmap * watch_bus ; /* D-Bus names => Unit object n:1 */
2013-07-10 23:10:53 +04:00
bool send_reloading_done ;
2010-08-12 00:37:10 +04:00
uint32_t current_job_id ;
2012-02-02 15:39:33 +04:00
uint32_t default_unit_job_id ;
2010-08-12 00:37:10 +04:00
2010-04-21 06:01:24 +04:00
/* Data specific to the Automount subsystem */
int dev_autofs_fd ;
2010-03-31 18:29:55 +04:00
/* Data specific to the cgroup subsystem */
2013-06-27 06:14:27 +04:00
Hashmap * cgroup_unit ;
CGroupControllerMask cgroup_supported ;
2013-06-20 05:45:08 +04:00
char * cgroup_root ;
2010-04-10 19:53:17 +04:00
2010-04-21 08:01:13 +04:00
int gc_marker ;
unsigned n_in_gc_queue ;
2011-02-21 17:32:17 +03:00
/* Make sure the user cannot accidentally unmount our cgroup
2010-06-18 22:15:34 +04:00
* file system */
int pin_cgroupfs_fd ;
2010-04-21 06:01:24 +04:00
/* Flags */
2012-09-18 19:11:12 +04:00
SystemdRunningAs running_as ;
2010-10-14 02:52:26 +04:00
ManagerExitCode exit_code : 5 ;
2010-04-18 05:07:42 +04:00
2010-04-21 06:01:24 +04:00
bool dispatching_load_queue : 1 ;
bool dispatching_dbus_queue : 1 ;
2011-03-30 02:47:50 +04:00
bool taint_usr : 1 ;
2014-07-07 21:25:31 +04:00
bool first_boot : 1 ;
2011-03-30 02:47:50 +04:00
2014-01-07 17:41:24 +04:00
bool test_run : 1 ;
2014-01-28 07:27:07 +04:00
ShowStatus show_status ;
2010-07-04 06:47:19 +04:00
bool confirm_spawn ;
systemd: do not output status messages once gettys are running
Make Type=idle communication bidirectional: when bootup is finished,
the manager, as before, signals idling Type=idle jobs to continue.
However, if the boot takes too long, idling jobs signal the manager
that they have had enough, wait a tiny bit more, and continue, taking
ownership of the console. The manager, when signalled that Type=idle
jobs are done, makes a note and will not write to the console anymore.
This is a cosmetic issue, but quite noticable, so let's just fix it.
Based on Harald Hoyer's patch.
https://bugs.freedesktop.org/show_bug.cgi?id=54247
http://unix.stackexchange.com/questions/51805/systemd-messages-after-starting-login/
2013-07-16 05:34:57 +04:00
bool no_console_output ;
2010-08-25 05:11:26 +04:00
2011-02-15 13:52:29 +03:00
ExecOutput default_std_output , default_std_error ;
2014-02-25 02:50:10 +04:00
usec_t default_restart_usec , default_timeout_start_usec , default_timeout_stop_usec ;
2013-11-04 20:47:43 +04:00
2013-11-08 19:01:22 +04:00
usec_t default_start_limit_interval ;
unsigned default_start_limit_burst ;
2014-02-25 02:50:10 +04:00
bool default_cpu_accounting ;
bool default_memory_accounting ;
bool default_blockio_accounting ;
2014-03-24 19:22:34 +04:00
usec_t default_timer_accuracy_usec ;
2014-03-05 05:29:58 +04:00
struct rlimit * rlimit [ _RLIMIT_MAX ] ;
2012-03-21 21:03:40 +04:00
2011-07-06 02:47:39 +04:00
/* non-zero if we are reloading or reexecuting, */
int n_reloading ;
2010-09-21 05:51:31 +04:00
unsigned n_installed_jobs ;
2010-09-23 17:38:42 +04:00
unsigned n_failed_jobs ;
2012-04-24 16:28:00 +04:00
2013-02-28 03:03:22 +04:00
/* Jobs in progress watching */
2013-02-26 15:09:41 +04:00
unsigned n_running_jobs ;
2013-02-28 03:01:10 +04:00
unsigned n_on_console ;
2013-02-28 03:03:22 +04:00
unsigned jobs_in_progress_iteration ;
2013-02-26 15:09:41 +04:00
2012-04-24 16:28:00 +04:00
/* Type=idle pipes */
systemd: do not output status messages once gettys are running
Make Type=idle communication bidirectional: when bootup is finished,
the manager, as before, signals idling Type=idle jobs to continue.
However, if the boot takes too long, idling jobs signal the manager
that they have had enough, wait a tiny bit more, and continue, taking
ownership of the console. The manager, when signalled that Type=idle
jobs are done, makes a note and will not write to the console anymore.
This is a cosmetic issue, but quite noticable, so let's just fix it.
Based on Harald Hoyer's patch.
https://bugs.freedesktop.org/show_bug.cgi?id=54247
http://unix.stackexchange.com/questions/51805/systemd-messages-after-starting-login/
2013-07-16 05:34:57 +04:00
int idle_pipe [ 4 ] ;
2013-11-20 00:12:59 +04:00
sd_event_source * idle_pipe_event_source ;
2012-05-09 03:24:50 +04:00
char * switch_root ;
char * switch_root_init ;
2013-09-26 22:14:24 +04:00
/* This maps all possible path prefixes to the units needing
* them . It ' s a hashmap with a path string as key and a Set as
* value where Unit objects are contained . */
Hashmap * units_requiring_mounts_for ;
2013-11-30 06:53:42 +04:00
/* Reference to the kdbus bus control fd */
int kdbus_fd ;
2014-08-06 13:45:36 +04:00
/* Used for processing polkit authorization responses */
Hashmap * polkit_registry ;
2014-08-22 18:36:38 +04:00
/* System wide startup timeouts */
usec_t start_timeout_usec ;
sd_event_source * start_timeout_event_source ;
FailureAction start_timeout_action ;
char * start_timeout_reboot_arg ;
2009-11-18 02:42:52 +03:00
} ;
2014-01-07 17:41:24 +04:00
int manager_new ( SystemdRunningAs running_as , bool test_run , Manager * * m ) ;
2009-11-18 02:42:52 +03:00
void manager_free ( Manager * m ) ;
2010-04-21 05:27:44 +04:00
int manager_enumerate ( Manager * m ) ;
int manager_startup ( Manager * m , FILE * serialization , FDSet * fds ) ;
2010-01-29 05:18:09 +03:00
2009-11-18 02:42:52 +03:00
Job * manager_get_job ( Manager * m , uint32_t id ) ;
2010-01-26 23:39:06 +03:00
Unit * manager_get_unit ( Manager * m , const char * name ) ;
2009-11-18 02:42:52 +03:00
2013-09-26 22:14:24 +04:00
int manager_get_unit_by_path ( Manager * m , const char * path , const char * suffix , Unit * * _found ) ;
2010-02-02 14:42:08 +03:00
int manager_get_job_from_dbus_path ( Manager * m , const char * s , Job * * _j ) ;
2010-02-01 05:33:24 +03:00
2013-11-20 00:12:59 +04:00
int manager_load_unit_prepare ( Manager * m , const char * name , const char * path , sd_bus_error * e , Unit * * _ret ) ;
int manager_load_unit ( Manager * m , const char * name , const char * path , sd_bus_error * e , Unit * * _ret ) ;
int manager_load_unit_from_dbus_path ( Manager * m , const char * s , sd_bus_error * e , Unit * * _u ) ;
2010-04-13 03:59:06 +04:00
2013-11-20 00:12:59 +04:00
int manager_add_job ( Manager * m , JobType type , Unit * unit , JobMode mode , bool force , sd_bus_error * e , Job * * _ret ) ;
int manager_add_job_by_name ( Manager * m , JobType type , const char * name , JobMode mode , bool force , sd_bus_error * e , Job * * _ret ) ;
2009-11-18 02:42:52 +03:00
2010-01-26 23:39:06 +03:00
void manager_dump_units ( Manager * s , FILE * f , const char * prefix ) ;
2010-01-20 06:02:39 +03:00
void manager_dump_jobs ( Manager * s , FILE * f , const char * prefix ) ;
2010-01-19 02:22:34 +03:00
2010-01-20 07:03:52 +03:00
void manager_clear_jobs ( Manager * m ) ;
2010-02-05 02:38:41 +03:00
unsigned manager_dispatch_load_queue ( Manager * m ) ;
2010-01-29 05:18:09 +03:00
2013-11-20 00:12:59 +04:00
int manager_environment_add ( Manager * m , char * * minus , char * * plus ) ;
2012-03-21 21:03:40 +04:00
int manager_set_default_rlimits ( Manager * m , struct rlimit * * default_rlimit ) ;
2010-08-30 23:31:40 +04:00
2010-01-24 02:39:29 +03:00
int manager_loop ( Manager * m ) ;
2010-01-24 00:56:47 +03:00
2010-04-16 01:16:16 +04:00
void manager_dispatch_bus_name_owner_changed ( Manager * m , const char * name , const char * old_owner , const char * new_owner ) ;
2010-07-20 22:54:33 +04:00
int manager_open_serialization ( Manager * m , FILE * * _f ) ;
2010-04-21 05:27:44 +04:00
2013-04-08 16:05:24 +04:00
int manager_serialize ( Manager * m , FILE * f , FDSet * fds , bool switching_root ) ;
2010-04-21 05:27:44 +04:00
int manager_deserialize ( Manager * m , FILE * f , FDSet * fds ) ;
int manager_reload ( Manager * m ) ;
2013-05-03 06:51:50 +04:00
bool manager_is_reloading_or_reexecuting ( Manager * m ) _pure_ ;
2013-03-14 21:12:27 +04:00
2010-08-31 02:23:34 +04:00
void manager_reset_failed ( Manager * m ) ;
2010-07-18 06:58:01 +04:00
2010-08-11 03:43:23 +04:00
void manager_send_unit_audit ( Manager * m , Unit * u , int type , bool success ) ;
2010-10-06 05:55:49 +04:00
void manager_send_unit_plymouth ( Manager * m , Unit * u ) ;
2010-08-11 03:43:23 +04:00
2013-04-26 04:57:41 +04:00
bool manager_unit_inactive_or_pending ( Manager * m , const char * name ) ;
2010-09-01 05:30:59 +04:00
2010-09-21 06:14:38 +04:00
void manager_check_finished ( Manager * m ) ;
2010-11-11 23:28:33 +03:00
void manager_run_generators ( Manager * m ) ;
void manager_undo_generators ( Manager * m ) ;
2012-01-12 08:09:06 +04:00
void manager_recheck_journal ( Manager * m ) ;
2011-03-18 06:31:22 +03:00
2014-01-28 07:27:07 +04:00
void manager_set_show_status ( Manager * m , ShowStatus mode ) ;
2014-07-07 21:25:31 +04:00
void manager_set_first_boot ( Manager * m , bool b ) ;
2013-10-16 05:17:09 +04:00
void manager_status_printf ( Manager * m , bool ephemeral , const char * status , const char * format , . . . ) _printf_ ( 4 , 5 ) ;
2014-01-28 07:48:18 +04:00
void manager_flip_auto_status ( Manager * m , bool enable ) ;
2012-11-22 03:38:55 +04:00
2013-09-26 22:14:24 +04:00
Set * manager_get_units_requiring_mounts_for ( Manager * m , const char * path ) ;
2014-03-03 20:14:07 +04:00
const char * manager_get_runtime_prefix ( Manager * m ) ;
2014-03-12 23:55:13 +04:00
ManagerState manager_state ( Manager * m ) ;
const char * manager_state_to_string ( ManagerState m ) _const_ ;
ManagerState manager_state_from_string ( const char * s ) _pure_ ;