diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index f6c9ae6940..fb608cd295 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1475,19 +1475,32 @@ static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bu return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed."); } -static int verify_run_space(const char *message, sd_bus_error *error) { +static int get_run_space(uint64_t *ret, sd_bus_error *error) { struct statvfs svfs; - uint64_t available; + + assert(ret); if (statvfs("/run/systemd", &svfs) < 0) return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m"); - available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize; + *ret = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize; + return 0; +} + +static int verify_run_space(const char *message, sd_bus_error *error) { + uint64_t available = 0; /* unnecessary, but used to trick out gcc's incorrect maybe-uninitialized warning */ + int r; + + assert(message); + + r = get_run_space(&available, error); + if (r < 0) + return r; if (available < RELOAD_DISK_SPACE_MIN) return sd_bus_error_setf(error, BUS_ERROR_DISK_FULL, - "%s, not enough space available on /run/systemd. " + "%s, not enough space available on /run/systemd/. " "Currently, %s are free, but a safety buffer of %s is enforced.", message, FORMAT_BYTES(available), @@ -1500,6 +1513,8 @@ int verify_run_space_and_log(const char *message) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; + assert(message); + r = verify_run_space(message, &error); if (r < 0) return log_error_errno(r, "%s", bus_error_message(&error, r)); @@ -1507,6 +1522,26 @@ int verify_run_space_and_log(const char *message) { return 0; } +static int verify_run_space_permissive(const char *message, sd_bus_error *error) { + uint64_t available = 0; /* unnecessary, but used to trick out gcc's incorrect maybe-uninitialized warning */ + int r; + + assert(message); + + r = get_run_space(&available, error); + if (r < 0) + return r; + + if (available < RELOAD_DISK_SPACE_MIN) + log_warning("Dangerously low amount of free space on /run/systemd/, %s.\n" + "Currently, %s are free, but %s are suggested. Proceeding anyway.", + message, + FORMAT_BYTES(available), + FORMAT_BYTES(RELOAD_DISK_SPACE_MIN)); + + return 0; +} + static void log_caller(sd_bus_message *message, Manager *manager, const char *method) { _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL; const char *comm = NULL; @@ -1709,22 +1744,13 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er _cleanup_free_ char *ri = NULL, *rt = NULL; const char *root, *init; Manager *m = ASSERT_PTR(userdata); - struct statvfs svfs; - uint64_t available; int r; assert(message); - if (statvfs("/run/systemd", &svfs) < 0) - return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m"); - - available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize; - - if (available < RELOAD_DISK_SPACE_MIN) - log_warning("Dangerously low amount of free space on /run/systemd, root switching might fail.\n" - "Currently, %s are free, but %s are suggested. Proceeding anyway.", - FORMAT_BYTES(available), - FORMAT_BYTES(RELOAD_DISK_SPACE_MIN)); + r = verify_run_space_permissive("root switching may fail", error); + if (r < 0) + return r; r = mac_selinux_access_check(message, "reboot", error); if (r < 0)