]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/home/homed-home.h
importd: unify setup of bus connectivity in one place
[thirdparty/systemd.git] / src / home / homed-home.h
index 4c24ee72a79798847b89641d6c9c7dcf98af2e5e..7d466cdd326f61c8f504d9ceaf8d2e767308fab5 100644 (file)
@@ -3,10 +3,12 @@
 
 typedef struct Home Home;
 
+#include "hashmap.h"
 #include "homed-manager.h"
 #include "homed-operation.h"
 #include "list.h"
 #include "ordered-set.h"
+#include "stat-util.h"
 #include "user-record.h"
 
 typedef enum HomeState {
@@ -21,6 +23,7 @@ typedef enum HomeState {
         HOME_ACTIVATING_FOR_ACQUIRE,  /* activating because Acquire() was called */
         HOME_DEACTIVATING,
         HOME_ACTIVE,                  /* logged in right now */
+        HOME_LINGERING,               /* not logged in anymore, but we didn't manage to deactivate (because some process keeps it busy?) but we'll keep trying */
         HOME_LOCKING,
         HOME_LOCKED,
         HOME_UNLOCKING,
@@ -37,12 +40,13 @@ typedef enum HomeState {
         HOME_AUTHENTICATING_WHILE_ACTIVE,
         HOME_AUTHENTICATING_FOR_ACQUIRE,  /* authenticating because Acquire() was called */
         _HOME_STATE_MAX,
-        _HOME_STATE_INVALID = -1
+        _HOME_STATE_INVALID = -EINVAL,
 } HomeState;
 
 static inline bool HOME_STATE_IS_ACTIVE(HomeState state) {
         return IN_SET(state,
                       HOME_ACTIVE,
+                      HOME_LINGERING,
                       HOME_UPDATING_WHILE_ACTIVE,
                       HOME_RESIZING_WHILE_ACTIVE,
                       HOME_PASSWD_WHILE_ACTIVE,
@@ -74,6 +78,35 @@ static inline bool HOME_STATE_IS_EXECUTING_OPERATION(HomeState state) {
                       HOME_AUTHENTICATING_FOR_ACQUIRE);
 }
 
+static inline bool HOME_STATE_SHALL_PIN(HomeState state) {
+        /* Like HOME_STATE_IS_ACTIVE() – but HOME_LINGERING is missing! */
+        return IN_SET(state,
+                      HOME_ACTIVE,
+                      HOME_UPDATING_WHILE_ACTIVE,
+                      HOME_RESIZING_WHILE_ACTIVE,
+                      HOME_PASSWD_WHILE_ACTIVE,
+                      HOME_AUTHENTICATING_WHILE_ACTIVE,
+                      HOME_AUTHENTICATING_FOR_ACQUIRE);
+}
+
+#define HOME_STATE_SHALL_REBALANCE(state) HOME_STATE_SHALL_PIN(state)
+
+static inline bool HOME_STATE_MAY_RETRY_DEACTIVATE(HomeState state) {
+        /* Indicates when to leave the deactivate retry timer active */
+        return IN_SET(state,
+                      HOME_ACTIVE,
+                      HOME_LINGERING,
+                      HOME_DEACTIVATING,
+                      HOME_LOCKING,
+                      HOME_UNLOCKING,
+                      HOME_UNLOCKING_FOR_ACQUIRE,
+                      HOME_UPDATING_WHILE_ACTIVE,
+                      HOME_RESIZING_WHILE_ACTIVE,
+                      HOME_PASSWD_WHILE_ACTIVE,
+                      HOME_AUTHENTICATING_WHILE_ACTIVE,
+                      HOME_AUTHENTICATING_FOR_ACQUIRE);
+}
+
 struct Home {
         Manager *manager;
         char *user_name;
@@ -84,7 +117,7 @@ struct Home {
         /* Note that the 'state' field is only set to a state while we are doing something (i.e. activating,
          * deactivating, creating, removing, and such), or when the home is an "unfixated" one. When we are
          * done with an operation we invalidate the state. This is hint for home_get_state() to check the
-         * state on request as needed from the mount table and similar.*/
+         * state on request as needed from the mount table and similar. */
         HomeState state;
         int signed_locally; /* signed only by us */
 
@@ -107,7 +140,7 @@ struct Home {
 
         /* The reading side of a FIFO stored in /run/systemd/home/, the writing side being used for reference
          * counting. The references dropped to zero as soon as we see EOF. This concept exists twice: once
-         * for clients that are fine if we suspend the home directory on system suspend, and once for cliets
+         * for clients that are fine if we suspend the home directory on system suspend, and once for clients
          * that are not ok with that. This allows us to determine for each home whether there are any clients
          * that support unsuspend. */
         sd_event_source *ref_event_source_please_suspend;
@@ -126,6 +159,21 @@ struct Home {
 
         /* Used to coalesce bus PropertiesChanged events */
         sd_event_source *deferred_change_event_source;
+
+        /* An fd to the top-level home directory we keep while logged in, to keep the dir busy */
+        int pin_fd;
+
+        /* A time event used to repeatedly try to unmount home dir after use if it didn't work on first try */
+        sd_event_source *retry_deactivate_event_source;
+
+        /* An fd that locks the backing file of LUKS home dirs with a BSD lock. */
+        int luks_lock_fd;
+
+        /* Space metrics during rebalancing */
+        uint64_t rebalance_size, rebalance_usage, rebalance_free, rebalance_min, rebalance_weight, rebalance_goal;
+
+        /* Whether a rebalance operation is pending */
+        bool rebalance_pending;
 };
 
 int home_new(Manager *m, UserRecord *hr, const char *sysfs, Home **ret);
@@ -138,21 +186,33 @@ int home_save_record(Home *h);
 int home_unlink_record(Home *h);
 
 int home_fixate(Home *h, UserRecord *secret, sd_bus_error *error);
-int home_activate(Home *h, UserRecord *secret, sd_bus_error *error);
+int home_activate(Home *h, bool if_referenced, UserRecord *secret, sd_bus_error *error);
 int home_authenticate(Home *h, UserRecord *secret, sd_bus_error *error);
 int home_deactivate(Home *h, bool force, sd_bus_error *error);
-int home_create(Home *h, UserRecord *secret, sd_bus_error *error);
+int home_create(Home *h, UserRecord *secret, Hashmap *blobs, uint64_t flags, sd_bus_error *error);
 int home_remove(Home *h, sd_bus_error *error);
-int home_update(Home *h, UserRecord *new_record, sd_bus_error *error);
+int home_update(Home *h, UserRecord *new_record, Hashmap *blobs, uint64_t flags, sd_bus_error *error);
 int home_resize(Home *h, uint64_t disk_size, UserRecord *secret, sd_bus_error *error);
 int home_passwd(Home *h, UserRecord *new_secret, UserRecord *old_secret, sd_bus_error *error);
 int home_unregister(Home *h, sd_bus_error *error);
 int home_lock(Home *h, sd_bus_error *error);
 int home_unlock(Home *h, UserRecord *secret, sd_bus_error *error);
 
+bool home_is_referenced(Home *h);
+bool home_shall_suspend(Home *h);
 HomeState home_get_state(Home *h);
 
-void home_process_notify(Home *h, char **l);
+int home_get_disk_status(
+                Home *h,
+                uint64_t *ret_disk_size,
+                uint64_t *ret_disk_usage,
+                uint64_t *ret_disk_free,
+                uint64_t *ret_disk_ceiling,
+                uint64_t *ret_disk_floor,
+                statfs_f_type_t *ret_fstype,
+                mode_t *ret_access_mode);
+
+void home_process_notify(Home *h, char **l, int fd);
 
 int home_killall(Home *h);
 
@@ -167,5 +227,9 @@ int home_set_current_message(Home *h, sd_bus_message *m);
 
 int home_wait_for_worker(Home *h);
 
+bool home_shall_rebalance(Home *h);
+
+bool home_is_busy(Home *h);
+
 const char *home_state_to_string(HomeState state);
 HomeState home_state_from_string(const char *s);