[systemd-devel] [PATCH 1/2] manager: add system-wide enumerate state
WaLyong Cho
walyong.cho at samsung.com
Wed Mar 12 03:13:56 PDT 2014
Enumerated states are added. That can have three state. startup, running
and shutdown. manager is starting up with startup state and change to
running if default job finish. And shutdown target is loaded then the
state will be changed to shutdown. This state can also be red
"GetSystemState" method call of manager interface.
---
src/core/dbus-manager.c | 36 ++++++++++++++++++++++++
src/core/manager.c | 48 ++++++++++++++++++++------------
src/core/manager.h | 9 ++++++
src/core/org.freedesktop.systemd1.conf | 4 +++
4 files changed, 79 insertions(+), 18 deletions(-)
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
index 30f28b6..4293f17 100644
--- a/src/core/dbus-manager.c
+++ b/src/core/dbus-manager.c
@@ -1361,6 +1361,41 @@ static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void
return sd_bus_reply_method_return(message, "s", default_target);
}
+static int method_get_system_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
+ _cleanup_free_ char *state = NULL;
+ Manager *m = userdata;
+ int r;
+
+ assert(bus);
+ assert(message);
+ assert(m);
+
+ r = selinux_access_check(bus, message, "status", error);
+ if (r < 0)
+ return r;
+
+ switch (m->system_state) {
+
+ case STATE_STARTUP:
+ state = strdup("startup");
+ break;
+
+ case STATE_RUNNING:
+ state = strdup("running");
+ break;
+
+ case STATE_SHUTDOWN:
+ state = strdup("shutdown");
+ break;
+
+ default:
+ return -EINVAL;
+
+ }
+
+ return sd_bus_reply_method_return(message, "s", state);
+}
+
static int send_unit_files_changed(sd_bus *bus, void *userdata) {
_cleanup_bus_message_unref_ sd_bus_message *message = NULL;
int r;
@@ -1660,6 +1695,7 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
+ SD_BUS_METHOD("GetSystemState", NULL, "s", method_get_system_state, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_SIGNAL("UnitNew", "so", 0),
SD_BUS_SIGNAL("UnitRemoved", "so", 0),
diff --git a/src/core/manager.c b/src/core/manager.c
index 78f4f3d..f088e94 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -491,6 +491,8 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) {
m->taint_usr = dir_is_empty("/usr") > 0;
+ m->system_state = STATE_STARTUP;
+
*_m = m;
return 0;
@@ -1793,6 +1795,27 @@ static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t use
return sd_event_source_set_enabled(source, SD_EVENT_ONESHOT);
}
+static bool manager_is_booting(Manager *m) {
+ assert(m);
+
+ if (manager_get_job(m, m->default_unit_job_id))
+ return true;
+
+ return false;
+}
+
+static bool manager_is_shutting_down(Manager *m) {
+ Unit *u;
+
+ assert(m);
+
+ u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
+ if (u)
+ return !!u->job;
+
+ return false;
+}
+
int manager_loop(Manager *m) {
int r;
@@ -1819,6 +1842,12 @@ int manager_loop(Manager *m) {
if (m->runtime_watchdog > 0 && m->running_as == SYSTEMD_SYSTEM)
watchdog_ping();
+ if (m->system_state == STATE_STARTUP && !manager_is_booting(m))
+ m->system_state = STATE_RUNNING;
+
+ if (m->system_state != STATE_SHUTDOWN && manager_is_shutting_down(m))
+ m->system_state = STATE_SHUTDOWN;
+
if (!ratelimit_test(&rl)) {
/* Yay, something is going seriously wrong, pause a little */
log_warning("Looping too fast. Throttling execution a little.");
@@ -2406,23 +2435,6 @@ int manager_reload(Manager *m) {
return r;
}
-static bool manager_is_booting_or_shutting_down(Manager *m) {
- Unit *u;
-
- assert(m);
-
- /* Is the initial job still around? */
- if (manager_get_job(m, m->default_unit_job_id))
- return true;
-
- /* Is there a job for the shutdown target? */
- u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
- if (u)
- return !!u->job;
-
- return false;
-}
-
bool manager_is_reloading_or_reexecuting(Manager *m) {
assert(m);
@@ -2814,7 +2826,7 @@ void manager_status_printf(Manager *m, bool ephemeral, const char *status, const
if (ephemeral && m->n_on_console > 0)
return;
- if (!manager_is_booting_or_shutting_down(m))
+ if (m->system_state == STATE_RUNNING)
return;
va_start(ap, format);
diff --git a/src/core/manager.h b/src/core/manager.h
index e014abd..5861896 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -35,6 +35,12 @@
typedef struct Manager Manager;
+typedef enum SystemState {
+ STATE_STARTUP,
+ STATE_RUNNING,
+ STATE_SHUTDOWN
+} SystemState;
+
typedef enum ManagerExitCode {
MANAGER_RUNNING,
MANAGER_EXIT,
@@ -255,6 +261,9 @@ struct Manager {
/* Reference to the kdbus bus control fd */
int kdbus_fd;
+
+ /* system wide state */
+ SystemState system_state;
};
int manager_new(SystemdRunningAs running_as, Manager **m);
diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf
index a375dce..ded089b 100644
--- a/src/core/org.freedesktop.systemd1.conf
+++ b/src/core/org.freedesktop.systemd1.conf
@@ -90,6 +90,10 @@
send_interface="org.freedesktop.systemd1.Manager"
send_member="GetDefaultTarget"/>
+ <allow send_destination="org.freedesktop.systemd1"
+ send_interface="org.freedesktop.systemd1.Manager"
+ send_member="GetSystemState"/>
+
<allow receive_sender="org.freedesktop.systemd1"/>
</policy>
--
1.7.9.5
More information about the systemd-devel
mailing list