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 {
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,
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,
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;
/* 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);
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);
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);