1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-01 00:51:24 +03:00

logind: add support for /run/nologin and /run/systemd/shutdown/scheduled

Port over more code from shutdownd and teach logind to write /run/nologin at
least 5 minutes before the system is going down, and
/run/systemd/shutdown/scheduled when a shutdown is scheduled.
This commit is contained in:
Daniel Mack 2015-04-23 17:11:28 +02:00
parent e2fa5721c3
commit 867c37f6bb
3 changed files with 94 additions and 0 deletions

View File

@ -1770,6 +1770,71 @@ static int method_suspend(sd_bus *bus, sd_bus_message *message, void *userdata,
error);
}
static int nologin_timeout_handler(
sd_event_source *s,
uint64_t usec,
void *userdata) {
Manager *m = userdata;
int r;
log_info("Creating /run/nologin, blocking further logins...");
r = write_string_file_atomic("/run/nologin", "System is going down.");
if (r < 0)
log_error_errno(r, "Failed to create /run/nologin: %m");
else
m->unlink_nologin = true;
return 0;
}
static int update_schedule_file(Manager *m) {
int r;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_free_ char *t = NULL, *temp_path = NULL;
assert(m);
r = mkdir_safe_label("/run/systemd/shutdown", 0755, 0, 0);
if (r < 0)
return log_error_errno(r, "Failed to create shutdown subdirectory: %m");
t = cescape(m->wall_message);
if (!t)
return log_oom();
r = fopen_temporary("/run/systemd/shutdown/scheduled", &f, &temp_path);
if (r < 0)
return log_error_errno(r, "Failed to save information about scheduled shutdowns: %m");
(void) fchmod(fileno(f), 0644);
fprintf(f,
"USEC="USEC_FMT"\n"
"WARN_WALL=%i\n"
"MODE=%s\n",
m->scheduled_shutdown_timeout,
m->enable_wall_messages,
m->scheduled_shutdown_type);
if (!isempty(m->wall_message))
fprintf(f, "WALL_MESSAGE=%s\n", t);
(void) fflush_and_check(f);
if (ferror(f) || rename(temp_path, "/run/systemd/shutdown/scheduled") < 0) {
log_error_errno(errno, "Failed to write information about scheduled shutdowns: %m");
r = -errno;
(void) unlink(temp_path);
(void) unlink("/run/systemd/shutdown/scheduled");
}
return r;
}
static int manager_scheduled_shutdown_handler(
sd_event_source *s,
uint64_t usec,
@ -1857,6 +1922,21 @@ static int method_schedule_shutdown(sd_bus *bus, sd_bus_message *message, void *
return log_oom();
}
if (m->nologin_timeout_source) {
r = sd_event_source_set_time(m->nologin_timeout_source, elapse);
if (r < 0)
return log_error_errno(r, "sd_event_source_set_time() failed: %m\n");
r = sd_event_source_set_enabled(m->nologin_timeout_source, SD_EVENT_ONESHOT);
if (r < 0)
return log_error_errno(r, "sd_event_source_set_enabled() failed: %m\n");
} else {
r = sd_event_add_time(m->event, &m->nologin_timeout_source,
CLOCK_REALTIME, elapse - 5 * USEC_PER_MINUTE, 0, nologin_timeout_handler, m);
if (r < 0)
return log_error_errno(r, "sd_event_add_time() failed: %m\n");
}
m->scheduled_shutdown_timeout = elapse;
r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_TTY|SD_BUS_CREDS_UID, &creds);
@ -1877,6 +1957,13 @@ static int method_schedule_shutdown(sd_bus *bus, sd_bus_message *message, void *
if (r < 0)
return r;
if (!isempty(type)) {
r = update_schedule_file(m);
if (r < 0)
return r;
} else
(void) unlink("/run/systemd/shutdown/scheduled");
return sd_bus_reply_method_return(message, NULL);
}
@ -1891,6 +1978,7 @@ static int method_cancel_scheduled_shutdown(sd_bus *bus, sd_bus_message *message
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);
free(m->scheduled_shutdown_type);
m->scheduled_shutdown_type = NULL;
m->scheduled_shutdown_timeout = 0;

View File

@ -145,6 +145,7 @@ static void manager_free(Manager *m) {
sd_event_source_unref(m->idle_action_event_source);
sd_event_source_unref(m->inhibit_timeout_source);
sd_event_source_unref(m->scheduled_shutdown_timeout_source);
sd_event_source_unref(m->nologin_timeout_source);
sd_event_source_unref(m->wall_message_timeout_source);
sd_event_source_unref(m->console_active_event_source);
@ -168,6 +169,9 @@ static void manager_free(Manager *m) {
if (m->udev)
udev_unref(m->udev);
if (m->unlink_nologin)
unlink("/run/nologin");
bus_verify_polkit_async_registry_free(m->polkit_registry);
sd_bus_unref(m->bus);

View File

@ -102,6 +102,8 @@ struct Manager {
sd_event_source *scheduled_shutdown_timeout_source;
uid_t scheduled_shutdown_uid;
char *scheduled_shutdown_tty;
sd_event_source *nologin_timeout_source;
bool unlink_nologin;
char *wall_message;
unsigned enable_wall_messages;