This file is part of systemd.
Copyright 2010 Lennart Poettering
-
- systemd is free software; you can redistribute it and/or modify it
- 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
- (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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <libmount.h>
#include <stdbool.h>
#include <stdio.h>
#include "list.h"
#include "ratelimit.h"
+struct libmnt_monitor;
+typedef struct Unit Unit;
+
/* Enforce upper limit how many names we allow */
#define MANAGER_MAX_NAMES 131072 /* 128K */
enum {
/* 0 = run normally */
- MANAGER_TEST_RUN_MINIMAL = 1, /* run test w/o generators */
- MANAGER_TEST_RUN_ENV_GENERATORS = 2, /* also run env generators */
- MANAGER_TEST_RUN_GENERATORS = 4, /* also run unit generators */
- MANAGER_TEST_FULL = MANAGER_TEST_RUN_ENV_GENERATORS | MANAGER_TEST_RUN_GENERATORS,
+ MANAGER_TEST_RUN_MINIMAL = 1 << 1, /* create basic data structures */
+ MANAGER_TEST_RUN_BASIC = 1 << 2, /* interact with the environment */
+ MANAGER_TEST_RUN_ENV_GENERATORS = 1 << 3, /* also run env generators */
+ MANAGER_TEST_RUN_GENERATORS = 1 << 4, /* also run unit generators */
+ MANAGER_TEST_FULL = MANAGER_TEST_RUN_BASIC | MANAGER_TEST_RUN_ENV_GENERATORS | MANAGER_TEST_RUN_GENERATORS,
};
assert_cc((MANAGER_TEST_FULL & UINT8_MAX) == MANAGER_TEST_FULL);
/* Units whose cgroup ran empty */
LIST_HEAD(Unit, cgroup_empty_queue);
+ /* Target units whose default target dependencies haven't been set yet */
+ LIST_HEAD(Unit, target_deps_queue);
+
sd_event *event;
- /* 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 */
+ /* This maps PIDs we care about to units that are interested in. We allow multiple units to he interested in
+ * the same PID and multiple PIDs to be relevant to the same unit. Since in most cases only a single unit will
+ * be interested in the same PID we use a somewhat special encoding here: the first unit interested in a PID is
+ * stored directly in the hashmap, keyed by the PID unmodified. If there are other units interested too they'll
+ * be stored in a NULL-terminated array, and keyed by the negative PID. This is safe as pid_t is signed and
+ * negative PIDs are not used for regular processes but process groups, which we don't care about in this
+ * context, but this allows us to use the negative range for our own purposes. */
+ Hashmap *watch_pids; /* pid => unit as well as -pid => array of units */
/* A set contains all units which cgroup should be refreshed after startup */
Set *startup_units;
int signal_fd;
sd_event_source *signal_event_source;
+ sd_event_source *sigchld_event_source;
+
int time_change_fd;
sd_event_source *time_change_event_source;
int user_lookup_fds[2];
sd_event_source *user_lookup_event_source;
+ sd_event_source *sync_bus_names_event_source;
+
UnitFileScope unit_file_scope;
LookupPaths lookup_paths;
Set *unit_path_cache;
/* Have we already printed the taint line if necessary? */
bool taint_logged:1;
+ /* Have we ever changed the "kernel.pid_max" sysctl? */
+ bool sysctl_pid_max_changed:1;
+
unsigned test_run_flags:8;
/* If non-zero, exit with the following value when the systemd
Hashmap *uid_refs;
Hashmap *gid_refs;
+ /* ExecRuntime, indexed by their owner unit id */
+ Hashmap *exec_runtime_by_id;
+
/* When the user hits C-A-D more than 7 times per 2s, do something immediately... */
RateLimit ctrl_alt_del_ratelimit;
EmergencyAction cad_burst_action;
int first_boot; /* tri-state */
- /* prefixes of e.g. RuntimeDirectory= */
+ /* Prefixes of e.g. RuntimeDirectory= */
char *prefix[_EXEC_DIRECTORY_TYPE_MAX];
+
+ /* Used in the SIGCHLD and sd_notify() message invocation logic to avoid that we dispatch the same event
+ * multiple times on the same unit. */
+ unsigned sigchldgen;
+ unsigned notifygen;
};
#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM)
#define MANAGER_IS_FINISHED(m) (dual_timestamp_is_set((m)->timestamps + MANAGER_TIMESTAMP_FINISH))
+/* The exit code is set to OK as soon as we enter the main loop, and set otherwise as soon as we are done with it */
+#define MANAGER_IS_RUNNING(m) ((m)->exit_code == MANAGER_OK)
+
int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **m);
Manager* manager_free(Manager *m);
+DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
-void manager_enumerate(Manager *m);
int manager_startup(Manager *m, FILE *serialization, FDSet *fds);
Job *manager_get_job(Manager *m, uint32_t id);
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_startable_unit_or_warn(Manager *m, const char *name, const char *path, Unit **ret);
int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u);
int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, sd_bus_error *e, Job **_ret);
void manager_check_finished(Manager *m);
+void manager_recheck_dbus(Manager *m);
void manager_recheck_journal(Manager *m);
void manager_set_show_status(Manager *m, ShowStatus mode);
Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path);
-void manager_set_exec_params(Manager *m, ExecParameters *p);
-
ManagerState manager_state(Manager *m);
int manager_update_failed_units(Manager *m, Unit *u, bool failed);
char *manager_taint_string(Manager *m);
+void manager_ref_console(Manager *m);
+void manager_unref_console(Manager *m);
+
const char *manager_state_to_string(ManagerState m) _const_;
ManagerState manager_state_from_string(const char *s) _pure_;