X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Funit.h;h=fbcaabe167ed346276c7523e311d59b6bec05952;hp=cfb38d0aae751e79eae95e685a8bfbd68c18fc68;hb=4ad490007b70e6ac18d3cb04fa2ed92eba1451fa;hpb=1b64d026af01277e332d10d9e67e2eed5a4ded28 diff --git a/src/core/unit.h b/src/core/unit.h index cfb38d0aa..fbcaabe16 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -1,7 +1,6 @@ /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ -#ifndef foounithfoo -#define foounithfoo +#pragma once /*** This file is part of systemd. @@ -24,11 +23,10 @@ #include #include +#include typedef struct Unit Unit; typedef struct UnitVTable UnitVTable; -typedef enum UnitType UnitType; -typedef enum UnitLoadState UnitLoadState; typedef enum UnitActiveState UnitActiveState; typedef enum UnitDependency UnitDependency; typedef struct UnitRef UnitRef; @@ -39,33 +37,10 @@ typedef struct UnitStatusMessageFormats UnitStatusMessageFormats; #include "list.h" #include "socket-util.h" #include "execute.h" +#include "cgroup.h" #include "condition.h" #include "install.h" - -enum UnitType { - UNIT_SERVICE = 0, - UNIT_SOCKET, - UNIT_TARGET, - UNIT_DEVICE, - UNIT_MOUNT, - UNIT_AUTOMOUNT, - UNIT_SNAPSHOT, - UNIT_TIMER, - UNIT_SWAP, - UNIT_PATH, - _UNIT_TYPE_MAX, - _UNIT_TYPE_INVALID = -1 -}; - -enum UnitLoadState { - UNIT_STUB, - UNIT_LOADED, - UNIT_ERROR, - UNIT_MERGED, - UNIT_MASKED, - _UNIT_LOAD_STATE_MAX, - _UNIT_LOAD_STATE_INVALID = -1 -}; +#include "unit-name.h" enum UnitActiveState { UNIT_ACTIVE, @@ -101,13 +76,15 @@ enum UnitDependency { UNIT_REQUISITE, UNIT_REQUISITE_OVERRIDABLE, UNIT_WANTS, - UNIT_BIND_TO, + UNIT_BINDS_TO, + UNIT_PART_OF, /* Inverse of the above */ UNIT_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */ UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' and 'requisite_overridable' is 'soft_required_by' */ UNIT_WANTED_BY, /* inverse of 'wants' */ - UNIT_BOUND_BY, /* inverse of 'bind_to' */ + UNIT_BOUND_BY, /* inverse of 'binds_to' */ + UNIT_CONSISTS_OF, /* inverse of 'part_of' */ /* Negative dependencies */ UNIT_CONFLICTS, /* inverse of 'conflicts' is 'conflicted_by' */ @@ -125,8 +102,8 @@ enum UnitDependency { UNIT_TRIGGERED_BY, /* Propagate reloads */ - UNIT_PROPAGATE_RELOAD_TO, - UNIT_PROPAGATE_RELOAD_FROM, + UNIT_PROPAGATES_RELOAD_TO, + UNIT_RELOAD_PROPAGATED_FROM, /* Reference information for GC logic */ UNIT_REFERENCES, /* Inverse of 'references' is 'referenced_by' */ @@ -138,8 +115,15 @@ enum UnitDependency { #include "manager.h" #include "job.h" -#include "cgroup.h" -#include "cgroup-attr.h" + +struct UnitRef { + /* Keeps tracks of references to a unit. This is useful so + * that we can merge two units if necessary and correct all + * references to them */ + + Unit* unit; + LIST_FIELDS(UnitRef, refs); +}; struct Unit { Manager *manager; @@ -161,8 +145,10 @@ struct Unit { char *fragment_path; /* if loaded from a config file this is the primary path to it */ char *source_path; /* if converted, the source file */ + char **dropin_paths; usec_t fragment_mtime; usec_t source_mtime; + usec_t dropin_mtime; /* If there is something to do with this unit, then this is the installed job for it */ Job *job; @@ -186,8 +172,11 @@ struct Unit { dual_timestamp inactive_enter_timestamp; /* Counterparts in the cgroup filesystem */ - CGroupBonding *cgroup_bondings; - CGroupAttribute *cgroup_attributes; + char *cgroup_path; + bool cgroup_realized; + CGroupControllerMask cgroup_mask; + + UnitRef slice; /* Per type list */ LIST_FIELDS(Unit, units_by_type); @@ -207,6 +196,9 @@ struct Unit { /* GC queue */ LIST_FIELDS(Unit, gc_queue); + /* CGroup realize members queue */ + LIST_FIELDS(Unit, cgroup_queue); + /* Used during GC sweeps */ unsigned gc_marker; @@ -246,13 +238,14 @@ struct Unit { /* Ignore this unit when snapshotting */ bool ignore_on_snapshot; - /* Did the last condition check suceed? */ + /* Did the last condition check succeed? */ bool condition_result; bool in_load_queue:1; bool in_dbus_queue:1; bool in_cleanup_queue:1; bool in_gc_queue:1; + bool in_cgroup_queue:1; bool sent_dbus_new_signal:1; @@ -261,15 +254,6 @@ struct Unit { bool in_audit:1; }; -struct UnitRef { - /* Keeps tracks of references to a unit. This is useful so - * that we can merge two units if necessary and correct all - * references to them */ - - Unit* unit; - LIST_FIELDS(UnitRef, refs); -}; - struct UnitStatusMessageFormats { const char *starting_stopping[2]; const char *finished_start_job[_JOB_RESULT_MAX]; @@ -286,13 +270,23 @@ struct UnitStatusMessageFormats { #include "snapshot.h" #include "swap.h" #include "path.h" +#include "slice.h" struct UnitVTable { - const char *suffix; - /* How much memory does an object of this unit type need */ size_t object_size; + /* If greater than 0, the offset into the object where + * ExecContext is found, if the unit type has that */ + size_t exec_context_offset; + + /* If greater than 0, the offset into the object where + * CGroupContext is found, if the unit type has that */ + size_t cgroup_context_offset; + + /* The name of the configuration file section with the private settings of this unit*/ + const char *private_section; + /* Config file sections this unit type understands, separated * by NUL chars */ const char *sections; @@ -312,7 +306,7 @@ struct UnitVTable { * UNIT_STUB if no configuration could be found. */ int (*load)(Unit *u); - /* If a a lot of units got created via enumerate(), this is + /* If a lot of units got created via enumerate(), this is * where to actually set the state and call unit_notify(). */ int (*coldplug)(Unit *u); @@ -322,7 +316,7 @@ struct UnitVTable { int (*stop)(Unit *u); int (*reload)(Unit *u); - int (*kill)(Unit *u, KillWho w, KillMode m, int signo, DBusError *error); + int (*kill)(Unit *u, KillWho w, int signo, DBusError *error); bool (*can_reload)(Unit *u); @@ -333,6 +327,9 @@ struct UnitVTable { /* Restore one item from the serialization */ int (*deserialize_item)(Unit *u, const char *key, const char *data, FDSet *fds); + /* Try to match up fds with what we need for this unit */ + int (*distribute_fds)(Unit *u, FDSet *fds); + /* Boils down the more complex internal state of this unit to * a simpler one that the engine can understand */ UnitActiveState (*active_state)(Unit *u); @@ -360,12 +357,12 @@ struct UnitVTable { /* Called whenever any of the cgroups this unit watches for * ran empty */ - void (*cgroup_notify_empty)(Unit *u); + void (*notify_cgroup_empty)(Unit *u); /* Called whenever a process of this unit sends us a message */ void (*notify_message)(Unit *u, pid_t pid, char **tags); - /* Called whenever a name thus Unit registered for comes or + /* Called whenever a name this Unit registered for comes or * goes away. */ void (*bus_name_owner_change)(Unit *u, const char *name, const char *old_owner, const char *new_owner); @@ -381,6 +378,13 @@ struct UnitVTable { /* Return the set of units that are following each other */ int (*following_set)(Unit *u, Set **s); + /* Invoked each time a unit this unit is triggering changes + * state or gains/loses a job */ + void (*trigger_notify)(Unit *u, Unit *trigger); + + /* Called whenever CLOCK_REALTIME made a jump */ + void (*time_change)(Unit *u); + /* This is called for each unit type and should be used to * enumerate existing devices and load them. However, * everything that is loaded here should still stay in @@ -427,6 +431,8 @@ extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; /* For casting the various unit types into a unit */ #define UNIT(u) (&(u)->meta) +#define UNIT_TRIGGER(u) ((Unit*) set_first((u)->dependencies[UNIT_TRIGGERS])) + DEFINE_CAST(SOCKET, Socket); DEFINE_CAST(TIMER, Timer); DEFINE_CAST(SERVICE, Service); @@ -437,6 +443,7 @@ DEFINE_CAST(AUTOMOUNT, Automount); DEFINE_CAST(SNAPSHOT, Snapshot); DEFINE_CAST(SWAP, Swap); DEFINE_CAST(PATH, Path); +DEFINE_CAST(SLICE, Slice); Unit *unit_new(Manager *m, size_t size); void unit_free(Unit *u); @@ -454,12 +461,6 @@ int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDep int unit_add_exec_dependencies(Unit *u, ExecContext *c); -int unit_add_cgroup(Unit *u, CGroupBonding *b); -int unit_add_cgroup_from_text(Unit *u, const char *name); -int unit_add_default_cgroups(Unit *u); -CGroupBonding* unit_get_default_cgroup(Unit *u); -int unit_add_cgroup_attribute(Unit *u, const char *controller, const char *name, const char *value, CGroupAttributeMapCallback map_callback); - int unit_choose_id(Unit *u, const char *name); int unit_set_description(Unit *u, const char *description); @@ -473,13 +474,15 @@ void unit_add_to_gc_queue(Unit *u); int unit_merge(Unit *u, Unit *other); int unit_merge_by_name(Unit *u, const char *other); -Unit *unit_follow_merge(Unit *u); +Unit *unit_follow_merge(Unit *u) _pure_; int unit_load_fragment_and_dropin(Unit *u); int unit_load_fragment_and_dropin_optional(Unit *u); int unit_load(Unit *unit); -const char *unit_description(Unit *u); +int unit_add_default_slice(Unit *u); + +const char *unit_description(Unit *u) _pure_; bool unit_has_name(Unit *u, const char *name); @@ -489,15 +492,16 @@ const char* unit_sub_state_to_string(Unit *u); void unit_dump(Unit *u, FILE *f, const char *prefix); -bool unit_can_reload(Unit *u); -bool unit_can_start(Unit *u); -bool unit_can_isolate(Unit *u); +bool unit_can_reload(Unit *u) _pure_; +bool unit_can_start(Unit *u) _pure_; +bool unit_can_isolate(Unit *u) _pure_; int unit_start(Unit *u); int unit_stop(Unit *u); int unit_reload(Unit *u); -int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error); +int unit_kill(Unit *u, KillWho w, int signo, DBusError *error); +int unit_kill_common(Unit *u, KillWho who, int signo, pid_t main_pid, pid_t control_pid, DBusError *error); void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success); @@ -507,7 +511,7 @@ void unit_unwatch_fd(Unit *u, Watch *w); int unit_watch_pid(Unit *u, pid_t pid); void unit_unwatch_pid(Unit *u, pid_t pid); -int unit_watch_timer(Unit *u, usec_t delay, Watch *w); +int unit_watch_timer(Unit *u, clockid_t, bool relative, usec_t usec, Watch *w); void unit_unwatch_timer(Unit *u, Watch *w); int unit_watch_bus_name(Unit *u, const char *name); @@ -522,12 +526,8 @@ char *unit_dbus_path(Unit *u); int unit_load_related_unit(Unit *u, const char *type, Unit **_found); int unit_get_related_unit(Unit *u, const char *type, Unit **_found); -char *unit_name_printf(Unit *u, const char* text); -char *unit_full_printf(Unit *u, const char *text); -char **unit_full_printf_strv(Unit *u, char **l); - -bool unit_can_serialize(Unit *u); -int unit_serialize(Unit *u, FILE *f, FDSet *fds); +bool unit_can_serialize(Unit *u) _pure_; +int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs); void unit_serialize_item_format(Unit *u, FILE *f, const char *key, const char *value, ...) _printf_attr_(4,5); void unit_serialize_item(Unit *u, FILE *f, const char *key, const char *value); int unit_deserialize(Unit *u, FILE *f, FDSet *fds); @@ -536,7 +536,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants); int unit_coldplug(Unit *u); -void unit_status_printf(Unit *u, const char *status, const char *format, ...); +void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_attr_(3, 0); bool unit_need_daemon_reload(Unit *u); @@ -544,17 +544,20 @@ void unit_reset_failed(Unit *u); Unit *unit_following(Unit *u); -bool unit_pending_inactive(Unit *u); -bool unit_pending_active(Unit *u); +const char *unit_slice_name(Unit *u); + +bool unit_stop_pending(Unit *u) _pure_; +bool unit_inactive_or_pending(Unit *u) _pure_; +bool unit_active_or_pending(Unit *u); int unit_add_default_target_dependency(Unit *u, Unit *target); -int unit_following_set(Unit *u, Set **s); +char *unit_default_cgroup_path(Unit *u); -UnitType unit_name_to_type(const char *n); -bool unit_name_is_valid(const char *n, bool template_ok); +int unit_following_set(Unit *u, Set **s); -void unit_trigger_on_failure(Unit *u); +void unit_start_on_failure(Unit *u); +void unit_trigger_notify(Unit *u); bool unit_condition_test(Unit *u); @@ -564,17 +567,34 @@ Unit* unit_ref_set(UnitRef *ref, Unit *u); void unit_ref_unset(UnitRef *ref); #define UNIT_DEREF(ref) ((ref).unit) +#define UNIT_ISSET(ref) (!!(ref).unit) int unit_add_one_mount_link(Unit *u, Mount *m); int unit_add_mount_links(Unit *u); -const char *unit_load_state_to_string(UnitLoadState i); -UnitLoadState unit_load_state_from_string(const char *s); +int unit_exec_context_defaults(Unit *u, ExecContext *c); + +ExecContext *unit_get_exec_context(Unit *u) _pure_; +CGroupContext *unit_get_cgroup_context(Unit *u) _pure_; + +int unit_write_drop_in(Unit *u, bool runtime, const char *name, const char *data); +int unit_remove_drop_in(Unit *u, bool runtime, const char *name); + +int unit_kill_context(Unit *u, KillContext *c, bool sigkill, pid_t main_pid, pid_t control_pid, bool main_pid_alien); + +const char *unit_active_state_to_string(UnitActiveState i) _const_; +UnitActiveState unit_active_state_from_string(const char *s) _pure_; + +const char *unit_dependency_to_string(UnitDependency i) _const_; +UnitDependency unit_dependency_from_string(const char *s) _pure_; -const char *unit_active_state_to_string(UnitActiveState i); -UnitActiveState unit_active_state_from_string(const char *s); +/* Macros which append UNIT= or USER_UNIT= to the message */ -const char *unit_dependency_to_string(UnitDependency i); -UnitDependency unit_dependency_from_string(const char *s); +#define log_full_unit(level, unit, ...) log_meta_object(level, __FILE__, __LINE__, __func__, getpid() == 1 ? "UNIT=" : "USER_UNIT=", unit, __VA_ARGS__) +#define log_debug_unit(unit, ...) log_full_unit(LOG_DEBUG, unit, __VA_ARGS__) +#define log_info_unit(unit, ...) log_full_unit(LOG_INFO, unit, __VA_ARGS__) +#define log_notice_unit(unit, ...) log_full_unit(LOG_NOTICE, unit, __VA_ARGS__) +#define log_warning_unit(unit, ...) log_full_unit(LOG_WARNING, unit, __VA_ARGS__) +#define log_error_unit(unit, ...) log_full_unit(LOG_ERR, unit, __VA_ARGS__) -#endif +#define log_struct_unit(level, unit, ...) log_struct(level, getpid() == 1 ? "UNIT=%s" : "USER_UNIT=%s", unit, __VA_ARGS__)