]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/home/homed-manager.c
homed: Create & advertise blob directory
[thirdparty/systemd.git] / src / home / homed-manager.c
index 810ecb23fcfc843b0334cc87a0d4788429c2432b..2e07e90f9c723857ff759e030baaa21a9ebb4fab 100644 (file)
@@ -42,6 +42,7 @@
 #include "quota-util.h"
 #include "random-util.h"
 #include "resize-fs.h"
+#include "rm-rf.h"
 #include "socket-util.h"
 #include "sort-util.h"
 #include "stat-util.h"
@@ -79,6 +80,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(homes_by_sysfs_hash_ops, char, pat
 
 static int on_home_inotify(sd_event_source *s, const struct inotify_event *event, void *userdata);
 static int manager_gc_images(Manager *m);
+static int manager_gc_blob(Manager *m);
 static int manager_enumerate_images(Manager *m);
 static int manager_assess_image(Manager *m, int dir_fd, const char *dir_path, const char *dentry_name);
 static void manager_revalidate_image(Manager *m, Home *h);
@@ -1627,6 +1629,9 @@ int manager_startup(Manager *m) {
         /* Let's clean up home directories whose devices got removed while we were not running */
         (void) manager_enqueue_gc(m, NULL);
 
+        /* Let's clean up blob directories for home dirs that no longer exist */
+        (void) manager_gc_blob(m);
+
         return 0;
 }
 
@@ -1715,6 +1720,29 @@ int manager_gc_images(Manager *m) {
         return 0;
 }
 
+static int manager_gc_blob(Manager *m) {
+        _cleanup_closedir_ DIR *d = NULL;
+        int r;
+
+        assert(m);
+
+        d = opendir(home_system_blob_dir());
+        if (!d) {
+                if (errno == ENOENT)
+                        return 0;
+                return log_error_errno(errno, "Failed to open %s: %m", home_system_blob_dir());
+        }
+
+        FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read system blob directory: %m"))
+                if (!hashmap_contains(m->homes_by_name, de->d_name)) {
+                        r = rm_rf_at(dirfd(d), de->d_name, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
+                        if (r < 0)
+                                log_warning_errno(r, "Failed to delete blob dir for missing user '%s', ignoring: %m", de->d_name);
+                }
+
+        return 0;
+}
+
 static int on_deferred_rescan(sd_event_source *s, void *userdata) {
         Manager *m = ASSERT_PTR(userdata);