struct cgroup *cgroup;
+ /* For the Unit::cgroup_bondings list */
+ LIST_FIELDS(CGroupBonding, by_unit);
+
+ /* For the Manager::cgroup_bondings hashmap */
+ LIST_FIELDS(CGroupBonding, by_path);
+
/* When shutting down, remove cgroup? */
bool clean_up:1;
/* Inherit parameters from parent group */
bool inherit:1;
-
- /* For the Unit::cgroup_bondings list */
- LIST_FIELDS(CGroupBonding, by_unit);
-
- /* For the Manager::cgroup_bondings hashmap */
- LIST_FIELDS(CGroupBonding, by_path);
};
int cgroup_bonding_realize(CGroupBonding *b);
} ExecOutput;
struct ExecStatus {
- pid_t pid;
usec_t start_timestamp;
usec_t exit_timestamp;
+ pid_t pid;
int code; /* as in siginfo_t::si_code */
int status; /* as in sigingo_t::si_status */
};
struct ExecContext {
char **environment;
- mode_t umask;
struct rlimit *rlimit[RLIMIT_NLIMITS];
char *working_directory, *root_directory;
+
+ mode_t umask;
int oom_adjust;
int nice;
int ioprio;
int cpu_sched_policy;
int cpu_sched_priority;
+
cpu_set_t cpu_affinity;
unsigned long timer_slack_ns;
- bool oom_adjust_set:1;
- bool nice_set:1;
- bool ioprio_set:1;
- bool cpu_sched_set:1;
- bool cpu_affinity_set:1;
- bool timer_slack_ns_set:1;
-
- /* This is not exposed to the user but available
- * internally. We need it to make sure that whenever we spawn
- * /bin/mount it is run in the same process group as us so
- * that the autofs logic detects that it belongs to us and we
- * don't enter a trigger loop. */
- bool no_setsid:1;
-
- bool cpu_sched_reset_on_fork;
- bool non_blocking;
-
ExecInput std_input;
ExecOutput std_output;
ExecOutput std_error;
- char *tty_path;
-
int syslog_priority;
char *syslog_identifier;
- cap_t capabilities;
- int secure_bits;
- uint64_t capability_bounding_set_drop;
+ char *tty_path;
/* Since resolving these names might might involve socket
* connections and we don't want to deadlock ourselves these
char *user;
char *group;
char **supplementary_groups;
+
+ uint64_t capability_bounding_set_drop;
+
+ cap_t capabilities;
+ int secure_bits;
+
+ bool cpu_sched_reset_on_fork;
+ bool non_blocking;
+
+ bool oom_adjust_set:1;
+ bool nice_set:1;
+ bool ioprio_set:1;
+ bool cpu_sched_set:1;
+ bool cpu_affinity_set:1;
+ bool timer_slack_ns_set:1;
+
+ /* This is not exposed to the user but available
+ * internally. We need it to make sure that whenever we spawn
+ * /bin/mount it is run in the same process group as us so
+ * that the autofs logic detects that it belongs to us and we
+ * don't enter a trigger loop. */
+ bool no_setsid:1;
};
typedef enum ExitStatus {
Job *subject;
Job *object;
- bool matters;
-
LIST_FIELDS(JobDependency, subject);
LIST_FIELDS(JobDependency, object);
+
+ bool matters;
};
struct Job {
Manager *manager;
- uint32_t id;
-
Unit *unit;
- JobType type;
- JobState state;
-
- bool installed:1;
- bool in_run_queue:1;
- bool matters_to_anchor:1;
- bool override:1;
- bool in_dbus_queue:1;
- bool sent_dbus_new_signal:1;
-
LIST_FIELDS(Job, transaction);
LIST_FIELDS(Job, run_queue);
LIST_FIELDS(Job, dbus_queue);
Job* marker;
unsigned generation;
+ uint32_t id;
+
+ JobType type;
+ JobState state;
+
+ bool installed:1;
+ bool in_run_queue:1;
+ bool matters_to_anchor:1;
+ bool override:1;
+ bool in_dbus_queue:1;
+ bool sent_dbus_new_signal:1;
};
Job* job_new(Manager *m, JobType type, Unit *unit);
struct Watch {
int fd;
WatchType type;
- bool fd_is_dupped;
union {
union Unit *unit;
DBusWatch *bus_watch;
DBusTimeout *bus_timeout;
bool socket_accept;
} data;
+ bool fd_is_dupped;
};
#include "unit.h"
Hashmap *transaction_jobs; /* Unit object => Job object list 1:1 */
JobDependency *transaction_anchor;
- bool dispatching_load_queue:1;
- bool dispatching_run_queue:1;
- bool dispatching_dbus_queue:1;
-
- bool request_api_bus_dispatch:1;
- bool request_system_bus_dispatch:1;
-
- bool utmp_reboot_written:1;
-
- bool confirm_spawn:1;
-
- ManagerExitCode exit_code:4;
- ManagerRunningAs running_as;
-
Hashmap *watch_pids; /* pid => Unit object n:1 */
+ Watch signal_watch;
+
int epoll_fd;
- Watch signal_watch;
+ unsigned n_snapshots;
char **unit_path;
char **sysvinit_path;
Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */
int32_t name_data_slot;
+ /* Data specific to the Automount subsystem */
+ int dev_autofs_fd;
+
/* Data specific to the cgroup subsystem */
Hashmap *cgroup_bondings; /* path string => CGroupBonding object 1:n */
char *cgroup_controller;
char *cgroup_hierarchy;
- /* Data specific to the Automount subsystem */
- int dev_autofs_fd;
+ /* Flags */
+ ManagerRunningAs running_as;
+ ManagerExitCode exit_code:4;
- /* Data specific to the Snapshot subsystem */
- unsigned n_snapshots;
+ bool dispatching_load_queue:1;
+ bool dispatching_run_queue:1;
+ bool dispatching_dbus_queue:1;
+
+ bool request_api_bus_dispatch:1;
+ bool request_system_bus_dispatch:1;
+
+ bool utmp_reboot_written:1;
+
+ bool confirm_spawn:1;
};
int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **m);
typedef struct RateLimit {
usec_t interval;
+ usec_t begin;
unsigned burst;
unsigned n_printed, n_missed;
- usec_t begin;
} RateLimit;
#define RATELIMIT_DEFINE(_name, _interval, _burst) \
struct SocketPort {
SocketType type;
+ int fd;
SocketAddress address;
char *path;
- int fd;
Watch fd_watch;
LIST_FIELDS(SocketPort, port);
* the job for it */
Job *job;
- bool in_load_queue:1;
- bool in_dbus_queue:1;
- bool in_cleanup_queue:1;
- bool sent_dbus_new_signal:1;
-
- /* If we go down, pull down everything that depends on us, too */
- bool recursive_stop;
-
- /* Garbage collect us we nobody wants or requires us anymore */
- bool stop_when_unneeded;
-
usec_t active_enter_timestamp;
usec_t active_exit_timestamp;
/* Cleanup queue */
LIST_FIELDS(Meta, cleanup_queue);
+
+ /* If we go down, pull down everything that depends on us, too */
+ bool recursive_stop;
+
+ /* Garbage collect us we nobody wants or requires us anymore */
+ bool stop_when_unneeded;
+
+ bool in_load_queue:1;
+ bool in_dbus_queue:1;
+ bool in_cleanup_queue:1;
+ bool sent_dbus_new_signal:1;
};
#include "service.h"
struct UnitVTable {
const char *suffix;
- /* Can units of this type have multiple names? */
- bool no_alias:1;
-
- /* If true units of this types can never have "Requires"
- * dependencies, because state changes can only be observed,
- * not triggered */
- bool no_requires:1;
-
- /* Instances make no sense for this type */
- bool no_instances:1;
-
- /* Exclude this type from snapshots */
- bool no_snapshots:1;
-
/* This should reset all type-specific variables. This should
* not allocate memory, and is called with zero-initialized
* data. It should hence only initialize variables that need
/* Type specific cleanups. */
void (*shutdown)(Manager *m);
+
+ /* Can units of this type have multiple names? */
+ bool no_alias:1;
+
+ /* If true units of this types can never have "Requires"
+ * dependencies, because state changes can only be observed,
+ * not triggered */
+ bool no_requires:1;
+
+ /* Instances make no sense for this type */
+ bool no_instances:1;
+
+ /* Exclude this type from snapshots */
+ bool no_snapshots:1;
};
extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX];