summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-04-28 16:14:32 +0200
committerLuca Boccassi <luca.boccassi@gmail.com>2023-04-28 23:27:20 +0100
commitc23e9b6a64b3bdf44127a69d5eeaa2c116b40aba (patch)
treed15ab65e614af96cdcc08ee4f6191c30656091fe /src/core
parent5ae89ef34774a777c5af7af48b1ad431d10a425e (diff)
downloadsystemd-c23e9b6a64b3bdf44127a69d5eeaa2c116b40aba.tar.gz
pid1: unify implemenation of /run/ disk space safety check a bit
reload/reexec currently used a separate implementation of the /run/ disk space check, different from the one used for switch-root, even though the code is mostly the same. The one difference is that the former checks are authoritative, the latter are just informational (that's because refusing a reload/reexec is relatively benign, but refusing a switch-root quite troublesome, since this code is entered when it's already "too late" to turn turn back, i.e. when the preparatory transaction to initiate the switch root are already fully executed. Let's share some code, and unify codepaths. (This is preparation for later addition of a "userspace reboot" concept) No change in behaviour, just refactoring.
Diffstat (limited to 'src/core')
-rw-r--r--src/core/dbus-manager.c58
1 files changed, 42 insertions, 16 deletions
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)