]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/mkfs-util.c
repart: add support for formatting newly created partitions
[thirdparty/systemd.git] / src / shared / mkfs-util.c
CommitLineData
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
9int 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
31int 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}