#include "strv.h"
#include "sync-util.h"
#include "tmpfile-util.h"
+#include "user-util.h"
/* Round down to the nearest 4K size. Given that newer hardware generally prefers 4K sectors, let's align our
* partitions to that too. In the worst case we'll waste 3.5K per partition that way, but I think I can live
host_size = 0, partition_offset = 0, partition_size = 0; /* Unnecessary initialization to appease gcc */
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
sd_id128_t partition_uuid, fs_uuid, luks_uuid, disk_uuid;
+ _cleanup_close_ int mount_fd = -1;
const char *fstype, *ip;
struct statfs sfs;
int r;
if (setup->root_fd < 0)
return log_error_errno(errno, "Failed to open user directory in mounted image file: %m");
+ (void) home_shift_uid(setup->root_fd, NULL, UID_NOBODY, h->uid, &mount_fd);
+
+ if (mount_fd >= 0) {
+ /* If we have established a new mount, then we can use that as new root fd to our home directory. */
+ safe_close(setup->root_fd);
+
+ setup->root_fd = fd_reopen(mount_fd, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
+ if (setup->root_fd < 0)
+ return log_error_errno(setup->root_fd, "Unable to convert mount fd into proper directory fd: %m");
+
+ mount_fd = safe_close(mount_fd);
+ }
+
r = home_populate(h, setup->root_fd);
if (r < 0)
return r;
if (r < 0)
return r;
- return home_mount_node(node, fstype, discard, flags);
+ r = home_mount_node(node, fstype, discard, flags);
+ if (r < 0)
+ return r;
+
+ r = mount_nofollow_verbose(LOG_ERR, NULL, HOME_RUNTIME_WORK_DIR, NULL, MS_PRIVATE, NULL);
+ if (r < 0) {
+ (void) umount_verbose(LOG_ERR, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW);
+ return r;
+ }
+
+ return 0;
}
int home_move_mount(const char *mount_suffix, const char *target) {
if (r < 0)
return r;
- r = umount_verbose(LOG_ERR, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW);
+ r = umount_recursive(HOME_RUNTIME_WORK_DIR, 0);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to unmount %s: %m", HOME_RUNTIME_WORK_DIR);
log_info("Moving to final mount point %s completed.", target);
return 0;
if (!setup->undo_mount)
return 0;
- r = umount_verbose(level, HOME_RUNTIME_WORK_DIR, UMOUNT_NOFOLLOW);
- if (r < 0)
- return r;
+ r = umount_recursive(HOME_RUNTIME_WORK_DIR, 0);
+ if (r < 0) {
+ if (level >= LOG_DEBUG) /* umount_recursive() does debug level logging anyway, no need to
+ * repeat that here */
+ return r;
+
+ /* If a higher log level is requested, the generate a non-debug mesage here too. */
+ return log_full_errno(level, r, "Failed to unmount mount tree below %s: %m", HOME_RUNTIME_WORK_DIR);
+ }
setup->undo_mount = false;
return 1;