]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/home/homework-mount.c
homed: make it easier to run multiple instances of homed
[thirdparty/systemd.git] / src / home / homework-mount.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include <sched.h>
4 #include <sys/mount.h>
5
6 #include "alloc-util.h"
7 #include "homework-mount.h"
8 #include "mkdir.h"
9 #include "mount-util.h"
10 #include "path-util.h"
11 #include "string-util.h"
12
13 static const char *mount_options_for_fstype(const char *fstype) {
14 if (streq(fstype, "ext4"))
15 return "noquota,user_xattr";
16 if (streq(fstype, "xfs"))
17 return "noquota";
18 if (streq(fstype, "btrfs"))
19 return "noacl";
20 return NULL;
21 }
22
23 int home_mount_node(const char *node, const char *fstype, bool discard, unsigned long flags) {
24 _cleanup_free_ char *joined = NULL;
25 const char *options, *discard_option;
26 int r;
27
28 options = mount_options_for_fstype(fstype);
29
30 discard_option = discard ? "discard" : "nodiscard";
31
32 if (options) {
33 joined = strjoin(options, ",", discard_option);
34 if (!joined)
35 return log_oom();
36
37 options = joined;
38 } else
39 options = discard_option;
40
41 r = mount_verbose(LOG_ERR, node, "/run/systemd/user-home-mount", fstype, flags|MS_RELATIME, strempty(options));
42 if (r < 0)
43 return r;
44
45 log_info("Mounting file system completed.");
46 return 0;
47 }
48
49 int home_unshare_and_mount(const char *node, const char *fstype, bool discard, unsigned long flags) {
50 int r;
51
52 if (unshare(CLONE_NEWNS) < 0)
53 return log_error_errno(errno, "Couldn't unshare file system namespace: %m");
54
55 r = mount_verbose(LOG_ERR, "/run", "/run", NULL, MS_SLAVE|MS_REC, NULL); /* Mark /run as MS_SLAVE in our new namespace */
56 if (r < 0)
57 return r;
58
59 (void) mkdir_p("/run/systemd/user-home-mount", 0700);
60
61 if (node)
62 return home_mount_node(node, fstype, discard, flags);
63
64 return 0;
65 }
66
67 int home_move_mount(const char *user_name_and_realm, const char *target) {
68 _cleanup_free_ char *subdir = NULL;
69 const char *d;
70 int r;
71
72 assert(user_name_and_realm);
73 assert(target);
74
75 if (user_name_and_realm) {
76 subdir = path_join("/run/systemd/user-home-mount/", user_name_and_realm);
77 if (!subdir)
78 return log_oom();
79
80 d = subdir;
81 } else
82 d = "/run/systemd/user-home-mount/";
83
84 (void) mkdir_p(target, 0700);
85
86 r = mount_verbose(LOG_ERR, d, target, NULL, MS_BIND, NULL);
87 if (r < 0)
88 return r;
89
90 r = umount_verbose("/run/systemd/user-home-mount");
91 if (r < 0)
92 return r;
93
94 log_info("Moving to final mount point %s completed.", target);
95 return 0;
96 }