#define SHUTDOWN_SCHEDULE_FILE "/run/systemd/shutdown/scheduled"
-static int update_schedule_file(Manager *m);
static void reset_scheduled_shutdown(Manager *m);
-static int manager_setup_shutdown_timers(Manager* m);
static int get_sender_session(
Manager *m,
uint64_t usec,
void *userdata) {
- Manager *m = userdata;
+ Manager *m = ASSERT_PTR(userdata);
log_info("Creating /run/nologin, blocking further logins...");
return LESS_BY(elapse, 5 * USEC_PER_MINUTE);
}
-void manager_load_scheduled_shutdown(Manager *m) {
- _cleanup_fclose_ FILE *f = NULL;
- _cleanup_free_ char *usec = NULL,
- *warn_wall = NULL,
- *mode = NULL,
- *wall_message = NULL,
- *uid = NULL,
- *tty = NULL;
- int r;
-
+static void reset_scheduled_shutdown(Manager *m) {
assert(m);
- r = parse_env_file(f, SHUTDOWN_SCHEDULE_FILE,
- "USEC", &usec,
- "WARN_WALL", &warn_wall,
- "MODE", &mode,
- "WALL_MESSAGE", &wall_message,
- "UID", &uid,
- "TTY", &tty);
-
- /* reset will delete the file */
- reset_scheduled_shutdown(m);
-
- if (r == -ENOENT)
- return;
- if (r < 0)
- return (void) log_debug_errno(r, "Failed to parse " SHUTDOWN_SCHEDULE_FILE ": %m");
-
- HandleAction handle = handle_action_from_string(mode);
- if (handle < 0)
- return (void) log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse scheduled shutdown type: %s", mode);
-
- if (!usec)
- return (void) log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "USEC is required");
- if (deserialize_usec(usec, &m->scheduled_shutdown_timeout) < 0)
- return;
-
- /* assign parsed type only after we know usec is also valid */
- m->scheduled_shutdown_action = handle;
-
- if (warn_wall) {
- r = parse_boolean(warn_wall);
- if (r < 0)
- log_debug_errno(r, "Failed to parse enabling wall messages");
- else
- m->enable_wall_messages = r;
- }
+ m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
+ m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
+ m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
- if (wall_message) {
- _cleanup_free_ char *unescaped = NULL;
- r = cunescape(wall_message, 0, &unescaped);
- if (r < 0)
- log_debug_errno(r, "Failed to parse wall message: %s", wall_message);
- else
- free_and_replace(m->wall_message, unescaped);
- }
+ m->scheduled_shutdown_action = _HANDLE_ACTION_INVALID;
+ m->scheduled_shutdown_timeout = USEC_INFINITY;
+ m->scheduled_shutdown_uid = UID_INVALID;
+ m->scheduled_shutdown_tty = mfree(m->scheduled_shutdown_tty);
+ m->shutdown_dry_run = false;
- if (uid) {
- r = parse_uid(uid, &m->scheduled_shutdown_uid);
- if (r < 0)
- log_debug_errno(r, "Failed to parse wall uid: %s", uid);
+ if (m->unlink_nologin) {
+ (void) unlink_or_warn("/run/nologin");
+ m->unlink_nologin = false;
}
- free_and_replace(m->scheduled_shutdown_tty, tty);
-
- r = manager_setup_shutdown_timers(m);
- if (r < 0)
- return reset_scheduled_shutdown(m);
-
- (void) manager_setup_wall_message_timer(m);
- (void) update_schedule_file(m);
-
- return;
+ (void) unlink(SHUTDOWN_SCHEDULE_FILE);
}
static int update_schedule_file(Manager *m) {
return log_error_errno(r, "Failed to write information about scheduled shutdowns: %m");
}
-static void reset_scheduled_shutdown(Manager *m) {
- assert(m);
-
- m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
- m->wall_message_timeout_source = sd_event_source_unref(m->wall_message_timeout_source);
- m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
-
- m->scheduled_shutdown_action = _HANDLE_ACTION_INVALID;
- m->scheduled_shutdown_timeout = USEC_INFINITY;
- m->scheduled_shutdown_uid = UID_INVALID;
- m->scheduled_shutdown_tty = mfree(m->scheduled_shutdown_tty);
- m->shutdown_dry_run = false;
-
- if (m->unlink_nologin) {
- (void) unlink_or_warn("/run/nologin");
- m->unlink_nologin = false;
- }
-
- (void) unlink(SHUTDOWN_SCHEDULE_FILE);
-}
-
static int manager_scheduled_shutdown_handler(
sd_event_source *s,
uint64_t usec,
return r;
}
+static int manager_setup_shutdown_timers(Manager* m) {
+ int r;
+
+ assert(m);
+
+ r = event_reset_time(m->event, &m->scheduled_shutdown_timeout_source,
+ CLOCK_REALTIME,
+ m->scheduled_shutdown_timeout, 0,
+ manager_scheduled_shutdown_handler, m,
+ 0, "scheduled-shutdown-timeout", true);
+ if (r < 0)
+ goto fail;
+
+ r = event_reset_time(m->event, &m->nologin_timeout_source,
+ CLOCK_REALTIME,
+ nologin_timeout_usec(m->scheduled_shutdown_timeout), 0,
+ nologin_timeout_handler, m,
+ 0, "nologin-timeout", true);
+ if (r < 0)
+ goto fail;
+
+ return 0;
+
+fail:
+ m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
+ m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
+
+ return r;
+}
+
+void manager_load_scheduled_shutdown(Manager *m) {
+ _cleanup_fclose_ FILE *f = NULL;
+ _cleanup_free_ char *usec = NULL,
+ *warn_wall = NULL,
+ *mode = NULL,
+ *wall_message = NULL,
+ *uid = NULL,
+ *tty = NULL;
+ int r;
+
+ assert(m);
+
+ r = parse_env_file(f, SHUTDOWN_SCHEDULE_FILE,
+ "USEC", &usec,
+ "WARN_WALL", &warn_wall,
+ "MODE", &mode,
+ "WALL_MESSAGE", &wall_message,
+ "UID", &uid,
+ "TTY", &tty);
+
+ /* reset will delete the file */
+ reset_scheduled_shutdown(m);
+
+ if (r == -ENOENT)
+ return;
+ if (r < 0)
+ return (void) log_debug_errno(r, "Failed to parse " SHUTDOWN_SCHEDULE_FILE ": %m");
+
+ HandleAction handle = handle_action_from_string(mode);
+ if (handle < 0)
+ return (void) log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse scheduled shutdown type: %s", mode);
+
+ if (!usec)
+ return (void) log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "USEC is required");
+ if (deserialize_usec(usec, &m->scheduled_shutdown_timeout) < 0)
+ return;
+
+ /* assign parsed type only after we know usec is also valid */
+ m->scheduled_shutdown_action = handle;
+
+ if (warn_wall) {
+ r = parse_boolean(warn_wall);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse enabling wall messages");
+ else
+ m->enable_wall_messages = r;
+ }
+
+ if (wall_message) {
+ _cleanup_free_ char *unescaped = NULL;
+ r = cunescape(wall_message, 0, &unescaped);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse wall message: %s", wall_message);
+ else
+ free_and_replace(m->wall_message, unescaped);
+ }
+
+ if (uid) {
+ r = parse_uid(uid, &m->scheduled_shutdown_uid);
+ if (r < 0)
+ log_debug_errno(r, "Failed to parse wall uid: %s", uid);
+ }
+
+ free_and_replace(m->scheduled_shutdown_tty, tty);
+
+ r = manager_setup_shutdown_timers(m);
+ if (r < 0)
+ return reset_scheduled_shutdown(m);
+
+ (void) manager_setup_wall_message_timer(m);
+ (void) update_schedule_file(m);
+
+ return;
+}
+
static int method_schedule_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = ASSERT_PTR(userdata);
HandleAction handle;
return sd_bus_reply_method_return(message, NULL);
}
-static int manager_setup_shutdown_timers(Manager* m) {
- int r;
-
- r = event_reset_time(m->event, &m->scheduled_shutdown_timeout_source,
- CLOCK_REALTIME,
- m->scheduled_shutdown_timeout, 0,
- manager_scheduled_shutdown_handler, m,
- 0, "scheduled-shutdown-timeout", true);
- if (r < 0)
- goto fail;
-
- r = event_reset_time(m->event, &m->nologin_timeout_source,
- CLOCK_REALTIME,
- nologin_timeout_usec(m->scheduled_shutdown_timeout), 0,
- nologin_timeout_handler, m,
- 0, "nologin-timeout", true);
- if (r < 0)
- goto fail;
-
- return 0;
-
-fail:
- m->scheduled_shutdown_timeout_source = sd_event_source_unref(m->scheduled_shutdown_timeout_source);
- m->nologin_timeout_source = sd_event_source_unref(m->nologin_timeout_source);
-
- return r;
-}
-
static int method_cancel_scheduled_shutdown(sd_bus_message *message, void *userdata, sd_bus_error *error) {
Manager *m = ASSERT_PTR(userdata);
const HandleActionData *a;