]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/mkfs-util.c
basic/utf8: add function to convert to ASCII
[thirdparty/systemd.git] / src / shared / mkfs-util.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
c95f9a23 2
3c9fbb99
ZJS
3#include <unistd.h>
4
c95f9a23
LP
5#include "id128-util.h"
6#include "mkfs-util.h"
7#include "path-util.h"
8#include "process-util.h"
0f2b2c48 9#include "stdio-util.h"
c95f9a23
LP
10#include "string-util.h"
11
12int mkfs_exists(const char *fstype) {
13 const char *mkfs;
14 int r;
15
16 assert(fstype);
17
18 if (STR_IN_SET(fstype, "auto", "swap")) /* these aren't real file system types, refuse early */
19 return -EINVAL;
20
21 mkfs = strjoina("mkfs.", fstype);
22 if (!filename_is_valid(mkfs)) /* refuse file system types with slashes and similar */
23 return -EINVAL;
24
f7bc0c32 25 r = find_executable(mkfs, NULL);
c95f9a23
LP
26 if (r == -ENOENT)
27 return false;
28 if (r < 0)
29 return r;
30
31 return true;
32}
33
34int make_filesystem(
35 const char *node,
36 const char *fstype,
37 const char *label,
38 sd_id128_t uuid,
39 bool discard) {
40
41 _cleanup_free_ char *mkfs = NULL;
4f05a11c
ZJS
42 char mangled_label[8 + 3 + 1],
43 vol_id[CONST_MAX(ID128_UUID_STRING_MAX, 8 + 1)] = {};
c95f9a23
LP
44 int r;
45
46 assert(node);
47 assert(fstype);
48 assert(label);
49
50 if (streq(fstype, "swap")) {
f7bc0c32 51 r = find_executable("mkswap", &mkfs);
c95f9a23
LP
52 if (r == -ENOENT)
53 return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "mkswap binary not available.");
54 if (r < 0)
55 return log_error_errno(r, "Failed to determine whether mkswap binary exists: %m");
56 } else {
57 r = mkfs_exists(fstype);
58 if (r < 0)
59 return log_error_errno(r, "Failed to determine whether mkfs binary for %s exists: %m", fstype);
60 if (r == 0)
61 return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "mkfs binary for %s is not available.", fstype);
62
63 mkfs = strjoin("mkfs.", fstype);
64 if (!mkfs)
65 return log_oom();
66 }
67
4f05a11c
ZJS
68 if (streq(fstype, "vfat")) {
69 /* Classic FAT only allows 11 character uppercase labels */
70 strncpy(mangled_label, label, sizeof(mangled_label)-1);
71 mangled_label[sizeof(mangled_label)-1] = 0;
72 ascii_strupper(mangled_label);
73 label = mangled_label;
74
75 xsprintf(vol_id, "%08" PRIx32,
76 ((uint32_t) uuid.bytes[0] << 24) |
77 ((uint32_t) uuid.bytes[1] << 16) |
78 ((uint32_t) uuid.bytes[2] << 8) |
79 ((uint32_t) uuid.bytes[3])); /* Take first 32 bytes of UUID */
80 }
81
82 if (isempty(vol_id))
83 id128_to_uuid_string(uuid, vol_id);
84
c95f9a23
LP
85 r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR, NULL);
86 if (r < 0)
87 return r;
88 if (r == 0) {
c95f9a23 89 /* Child */
4f05a11c
ZJS
90
91 /* When changing this conditional, also adjust the log statement below. */
8e93a614
ZJS
92 if (streq(fstype, "ext2"))
93 (void) execlp(mkfs, mkfs,
4f05a11c 94 "-q",
8e93a614 95 "-L", label,
4f05a11c 96 "-U", vol_id,
8e93a614
ZJS
97 "-I", "256",
98 "-m", "0",
99 "-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1",
100 node, NULL);
101
102 else if (STR_IN_SET(fstype, "ext3", "ext4"))
c95f9a23 103 (void) execlp(mkfs, mkfs,
4f05a11c 104 "-q",
85b55869 105 "-L", label,
4f05a11c 106 "-U", vol_id,
85b55869
LP
107 "-I", "256",
108 "-O", "has_journal",
109 "-m", "0",
44cdeb6e 110 "-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1",
85b55869 111 node, NULL);
c95f9a23
LP
112
113 else if (streq(fstype, "btrfs")) {
44cdeb6e 114 (void) execlp(mkfs, mkfs,
4f05a11c 115 "-q",
44cdeb6e 116 "-L", label,
4f05a11c 117 "-U", vol_id,
44cdeb6e
ZJS
118 node,
119 discard ? NULL : "--nodiscard",
120 NULL);
c95f9a23
LP
121
122 } else if (streq(fstype, "xfs")) {
123 const char *j;
124
4f05a11c 125 j = strjoina("uuid=", vol_id);
44cdeb6e
ZJS
126
127 (void) execlp(mkfs, mkfs,
4f05a11c 128 "-q",
44cdeb6e
ZJS
129 "-L", label,
130 "-m", j,
131 "-m", "reflink=1",
132 node,
133 discard ? NULL : "-K",
134 NULL);
c95f9a23 135
4f05a11c 136 } else if (streq(fstype, "vfat"))
0f2b2c48
LP
137
138 (void) execlp(mkfs, mkfs,
139 "-i", vol_id,
4f05a11c 140 "-n", label,
0f2b2c48
LP
141 "-F", "32", /* yes, we force FAT32 here */
142 node, NULL);
143
4f05a11c
ZJS
144 else if (streq(fstype, "swap"))
145 /* TODO: add --quiet here if
146 * https://github.com/util-linux/util-linux/issues/1499 resolved. */
c95f9a23
LP
147
148 (void) execlp(mkfs, mkfs,
85b55869 149 "-L", label,
4f05a11c 150 "-U", vol_id,
85b55869 151 node, NULL);
c95f9a23 152
4f05a11c 153 else
c95f9a23
LP
154 /* Generic fallback for all other file systems */
155 (void) execlp(mkfs, mkfs, node, NULL);
156
157 log_error_errno(errno, "Failed to execute %s: %m", mkfs);
158
159 _exit(EXIT_FAILURE);
160 }
161
4f05a11c
ZJS
162 if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "btrfs", "xfs", "vfat", "swap"))
163 log_info("%s successfully formatted as %s (label \"%s\", uuid %s)",
164 node, fstype, label, vol_id);
165 else
166 log_info("%s successfully formatted as %s (no label or uuid specified)",
167 node, fstype);
168
c95f9a23
LP
169 return 0;
170}