]>
Commit | Line | Data |
---|---|---|
c95f9a23 LP |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | ||
3 | #include "id128-util.h" | |
4 | #include "mkfs-util.h" | |
5 | #include "path-util.h" | |
6 | #include "process-util.h" | |
7 | #include "string-util.h" | |
8 | ||
9 | int mkfs_exists(const char *fstype) { | |
10 | const char *mkfs; | |
11 | int r; | |
12 | ||
13 | assert(fstype); | |
14 | ||
15 | if (STR_IN_SET(fstype, "auto", "swap")) /* these aren't real file system types, refuse early */ | |
16 | return -EINVAL; | |
17 | ||
18 | mkfs = strjoina("mkfs.", fstype); | |
19 | if (!filename_is_valid(mkfs)) /* refuse file system types with slashes and similar */ | |
20 | return -EINVAL; | |
21 | ||
22 | r = find_binary(mkfs, NULL); | |
23 | if (r == -ENOENT) | |
24 | return false; | |
25 | if (r < 0) | |
26 | return r; | |
27 | ||
28 | return true; | |
29 | } | |
30 | ||
31 | int make_filesystem( | |
32 | const char *node, | |
33 | const char *fstype, | |
34 | const char *label, | |
35 | sd_id128_t uuid, | |
36 | bool discard) { | |
37 | ||
38 | _cleanup_free_ char *mkfs = NULL; | |
39 | int r; | |
40 | ||
41 | assert(node); | |
42 | assert(fstype); | |
43 | assert(label); | |
44 | ||
45 | if (streq(fstype, "swap")) { | |
46 | r = find_binary("mkswap", &mkfs); | |
47 | if (r == -ENOENT) | |
48 | return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "mkswap binary not available."); | |
49 | if (r < 0) | |
50 | return log_error_errno(r, "Failed to determine whether mkswap binary exists: %m"); | |
51 | } else { | |
52 | r = mkfs_exists(fstype); | |
53 | if (r < 0) | |
54 | return log_error_errno(r, "Failed to determine whether mkfs binary for %s exists: %m", fstype); | |
55 | if (r == 0) | |
56 | return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "mkfs binary for %s is not available.", fstype); | |
57 | ||
58 | mkfs = strjoin("mkfs.", fstype); | |
59 | if (!mkfs) | |
60 | return log_oom(); | |
61 | } | |
62 | ||
63 | r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR, NULL); | |
64 | if (r < 0) | |
65 | return r; | |
66 | if (r == 0) { | |
67 | char suuid[ID128_UUID_STRING_MAX]; | |
68 | ||
69 | /* Child */ | |
70 | id128_to_uuid_string(uuid, suuid); | |
71 | ||
72 | if (streq(fstype, "ext4")) | |
73 | (void) execlp(mkfs, mkfs, | |
74 | "-L", label, | |
75 | "-U", suuid, | |
76 | "-I", "256", | |
77 | "-O", "has_journal", | |
78 | "-m", "0", | |
79 | "-E", discard ? "lazy_itable_init=1,discard" : "lazy_itable_init=1,nodiscard", | |
80 | node, NULL); | |
81 | ||
82 | else if (streq(fstype, "btrfs")) { | |
83 | if (discard) | |
84 | (void) execlp(mkfs, mkfs, "-L", label, "-U", suuid, node, NULL); | |
85 | else | |
86 | (void) execlp(mkfs, mkfs, "-L", label, "-U", suuid, "--nodiscard", node, NULL); | |
87 | ||
88 | } else if (streq(fstype, "xfs")) { | |
89 | const char *j; | |
90 | ||
91 | j = strjoina("uuid=", suuid); | |
92 | if (discard) | |
93 | (void) execlp(mkfs, mkfs, "-L", label, "-m", j, "-m", "reflink=1", node, NULL); | |
94 | else | |
95 | (void) execlp(mkfs, mkfs, "-L", label, "-m", j, "-m", "reflink=1", "-K", node, NULL); | |
96 | ||
97 | } else if (streq(fstype, "swap")) { | |
98 | ||
99 | (void) execlp(mkfs, mkfs, | |
100 | "-L", label, | |
101 | "-U", suuid, | |
102 | node, NULL); | |
103 | ||
104 | } else | |
105 | /* Generic fallback for all other file systems */ | |
106 | (void) execlp(mkfs, mkfs, node, NULL); | |
107 | ||
108 | log_error_errno(errno, "Failed to execute %s: %m", mkfs); | |
109 | ||
110 | _exit(EXIT_FAILURE); | |
111 | } | |
112 | ||
113 | return 0; | |
114 | } |