diff --git a/src/basic/fs-util.c b/src/basic/fs-util.c index c96c7d0d25..47edcbb04f 100644 --- a/src/basic/fs-util.c +++ b/src/basic/fs-util.c @@ -554,6 +554,17 @@ int tmp_dir(const char **ret) { return tmp_dir_internal("/tmp", ret); } +int unlink_or_warn(const char *filename) { + if (unlink(filename) < 0 && errno != ENOENT) + /* If the file doesn't exist and the fs simply was read-only (in which + * case unlink() returns EROFS even if the file doesn't exist), don't + * complain */ + if (errno != EROFS || access(filename, F_OK) >= 0) + return log_error_errno(errno, "Failed to remove \"%s\": %m", filename); + + return 0; +} + int inotify_add_watch_fd(int fd, int what, uint32_t mask) { char path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; int r; diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h index ae40d6d37f..acb83dfd83 100644 --- a/src/basic/fs-util.h +++ b/src/basic/fs-util.h @@ -64,6 +64,8 @@ int get_files_in_directory(const char *path, char ***list); int tmp_dir(const char **ret); int var_tmp_dir(const char **ret); +int unlink_or_warn(const char *filename); + #define INOTIFY_EVENT_MAX (sizeof(struct inotify_event) + NAME_MAX + 1) #define FOREACH_INOTIFY_EVENT(e, buffer, sz) \ diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index ed9eba1ee0..aa4bbf7739 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -2010,7 +2010,7 @@ static void reset_scheduled_shutdown(Manager *m) { m->shutdown_dry_run = false; if (m->unlink_nologin) { - (void) unlink("/run/nologin"); + (void) unlink_or_warn("/run/nologin"); m->unlink_nologin = false; } diff --git a/src/login/logind.c b/src/login/logind.c index d9b5f026cf..0a869ba447 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -35,6 +35,7 @@ #include "dirent-util.h" #include "fd-util.h" #include "format-util.h" +#include "fs-util.h" #include "logind.h" #include "process-util.h" #include "selinux-util.h" @@ -183,7 +184,7 @@ static void manager_free(Manager *m) { udev_unref(m->udev); if (m->unlink_nologin) - (void) unlink("/run/nologin"); + (void) unlink_or_warn("/run/nologin"); bus_verify_polkit_async_registry_free(m->polkit_registry); diff --git a/src/user-sessions/user-sessions.c b/src/user-sessions/user-sessions.c index 795766a657..1aed9adae7 100644 --- a/src/user-sessions/user-sessions.c +++ b/src/user-sessions/user-sessions.c @@ -23,12 +23,14 @@ #include "fileio.h" #include "fileio-label.h" +#include "fs-util.h" #include "log.h" #include "selinux-util.h" #include "string-util.h" #include "util.h" int main(int argc, char*argv[]) { + int r, k; if (argc != 2) { log_error("This program requires one argument."); @@ -44,30 +46,12 @@ int main(int argc, char*argv[]) { mac_selinux_init(); if (streq(argv[1], "start")) { - int r = 0; - - if (unlink("/run/nologin") < 0 && errno != ENOENT) - r = log_error_errno(errno, - "Failed to remove /run/nologin file: %m"); - - if (unlink("/etc/nologin") < 0 && errno != ENOENT) { - /* If the file doesn't exist and /etc simply - * was read-only (in which case unlink() - * returns EROFS even if the file doesn't - * exist), don't complain */ - - if (errno != EROFS || access("/etc/nologin", F_OK) >= 0) { - log_error_errno(errno, "Failed to remove /etc/nologin file: %m"); - return EXIT_FAILURE; - } - } - - if (r < 0) + r = unlink_or_warn("/run/nologin"); + k = unlink_or_warn("/etc/nologin"); + if (r < 0 || k < 0) return EXIT_FAILURE; } else if (streq(argv[1], "stop")) { - int r; - r = write_string_file_atomic_label("/run/nologin", "System is going down."); if (r < 0) { log_error_errno(r, "Failed to create /run/nologin: %m");