mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-28 07:21:32 +03:00
homework: rework how we disassemble a home dir in home_deactivate()
Let's first move the home dir to a new mount point that is only visible in our own private namespace. Then, do FITRIM and stuff there, so that we know the regular userspace can't interfere with that, and we know that the home fs is not used anymore. (This will become even more important once we add auto-grow/auto-shrink for home dirs)
This commit is contained in:
parent
e2f8c1124d
commit
a71a0693cd
@ -1020,16 +1020,6 @@ int run_fitrim(int root_fd) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int run_fitrim_by_path(const char *root_path) {
|
||||
_cleanup_close_ int root_fd = -1;
|
||||
|
||||
root_fd = open(root_path, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
|
||||
if (root_fd < 0)
|
||||
return log_error_errno(errno, "Failed to open file system '%s' for trimming: %m", root_path);
|
||||
|
||||
return run_fitrim(root_fd);
|
||||
}
|
||||
|
||||
int run_fallocate(int backing_fd, const struct stat *st) {
|
||||
struct stat stbuf;
|
||||
|
||||
@ -1528,15 +1518,17 @@ int home_deactivate_luks(UserRecord *h, HomeSetup *setup) {
|
||||
return we_detached;
|
||||
}
|
||||
|
||||
int home_trim_luks(UserRecord *h) {
|
||||
int home_trim_luks(UserRecord *h, HomeSetup *setup) {
|
||||
assert(h);
|
||||
assert(setup);
|
||||
assert(setup->root_fd >= 0);
|
||||
|
||||
if (!user_record_luks_offline_discard(h)) {
|
||||
log_debug("Not trimming on logout.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) run_fitrim_by_path(user_record_home_directory(h));
|
||||
(void) run_fitrim(setup->root_fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ int home_setup_luks(UserRecord *h, HomeSetupFlags flags, const char *force_image
|
||||
|
||||
int home_activate_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache, UserRecord **ret_home);
|
||||
int home_deactivate_luks(UserRecord *h, HomeSetup *setup);
|
||||
int home_trim_luks(UserRecord *h);
|
||||
int home_trim_luks(UserRecord *h, HomeSetup *setup);
|
||||
|
||||
int home_store_header_identity_luks(UserRecord *h, HomeSetup *setup, UserRecord *old_home);
|
||||
|
||||
@ -39,7 +39,6 @@ static inline uint64_t luks_volume_key_size_convert(struct crypt_device *cd) {
|
||||
}
|
||||
|
||||
int run_fitrim(int root_fd);
|
||||
int run_fitrim_by_path(const char *root_path);
|
||||
int run_fallocate(int backing_fd, const struct stat *st);
|
||||
int run_fallocate_by_path(const char *backing_path);
|
||||
int run_mark_dirty(int fd, bool b);
|
||||
|
@ -924,21 +924,47 @@ static int home_deactivate(UserRecord *h, bool force) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == USER_TEST_MOUNTED) {
|
||||
if (user_record_storage(h) == USER_LUKS) {
|
||||
r = home_trim_luks(h);
|
||||
/* Before we do anything, let's move the home mount away. */
|
||||
r = home_unshare_and_mkdir();
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = mount_nofollow_verbose(LOG_ERR, user_record_home_directory(h), HOME_RUNTIME_WORK_DIR, NULL, MS_BIND, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
setup.undo_mount = true; /* remember to unmount the new bind mount from HOME_RUNTIME_WORK_DIR */
|
||||
|
||||
/* Let's explicitly open the new root fs, using the moved path */
|
||||
setup.root_fd = open(HOME_RUNTIME_WORK_DIR, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
|
||||
if (setup.root_fd < 0)
|
||||
return log_error_errno(errno, "Failed to open moved home directory: %m");
|
||||
|
||||
/* Now get rid of the home at its original place (we only keep the bind mount we created above) */
|
||||
r = umount_verbose(LOG_ERR, user_record_home_directory(h), UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (user_record_storage(h) == USER_LUKS)
|
||||
(void) home_trim_luks(h, &setup);
|
||||
|
||||
/* Sync explicitly, so that the drop caches logic below can work as documented */
|
||||
r = syncfs_path(AT_FDCWD, user_record_home_directory(h));
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to synchronize home directory, ignoring: %m");
|
||||
if (syncfs(setup.root_fd) < 0)
|
||||
log_debug_errno(errno, "Failed to synchronize home directory, ignoring: %m");
|
||||
else
|
||||
log_info("Syncing completed.");
|
||||
|
||||
if (umount2(user_record_home_directory(h), UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0)) < 0)
|
||||
return log_error_errno(errno, "Failed to unmount %s: %m", user_record_home_directory(h));
|
||||
setup.root_fd = safe_close(setup.root_fd);
|
||||
|
||||
/* Now get rid of the bind mount, too */
|
||||
r = umount_verbose(LOG_ERR, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW | (force ? MNT_FORCE|MNT_DETACH : 0));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
setup.undo_mount = false; /* Remember that the bind mount doesn't need to be unmounted anymore */
|
||||
|
||||
if (user_record_drop_caches(h))
|
||||
setup.do_drop_caches = true;
|
||||
|
||||
log_info("Unmounting completed.");
|
||||
done = true;
|
||||
@ -956,8 +982,10 @@ static int home_deactivate(UserRecord *h, bool force) {
|
||||
if (!done)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOEXEC), "Home is not active.");
|
||||
|
||||
if (user_record_drop_caches(h))
|
||||
if (setup.do_drop_caches) {
|
||||
setup.do_drop_caches = false;
|
||||
drop_caches_now();
|
||||
}
|
||||
|
||||
log_info("Everything completed.");
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user