]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/partition/makefs.c
Merge pull request #8417 from brauner/2018-03-09/add_bind_mount_fallback_to_private_d...
[thirdparty/systemd.git] / src / partition / makefs.c
1 /***
2 SPDX-License-Identifier: LGPL-2.1+
3
4 This file is part of systemd.
5
6 Copyright 2017 Zbigniew Jędrzejewski-Szmek
7 ***/
8
9 #include <fcntl.h>
10 #include <signal.h>
11 #include <sys/prctl.h>
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 #include <unistd.h>
15
16 #include "alloc-util.h"
17 #include "dissect-image.h"
18 #include "process-util.h"
19 #include "signal-util.h"
20 #include "string-util.h"
21
22 static int makefs(const char *type, const char *device) {
23 const char *mkfs;
24 pid_t pid;
25 int r;
26
27 if (streq(type, "swap"))
28 mkfs = "/sbin/mkswap";
29 else
30 mkfs = strjoina("/sbin/mkfs.", type);
31 if (access(mkfs, X_OK) != 0)
32 return log_error_errno(errno, "%s is not executable: %m", mkfs);
33
34 r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
35 if (r < 0)
36 return r;
37 if (r == 0) {
38 const char *cmdline[3] = { mkfs, device, NULL };
39
40 /* Child */
41
42 execv(cmdline[0], (char**) cmdline);
43 _exit(EXIT_FAILURE);
44 }
45
46 return wait_for_terminate_and_check(mkfs, pid, WAIT_LOG);
47 }
48
49 int main(int argc, char *argv[]) {
50 const char *device, *type;
51 _cleanup_free_ char *detected = NULL;
52 struct stat st;
53 int r;
54
55 log_set_target(LOG_TARGET_AUTO);
56 log_parse_environment();
57 log_open();
58
59 if (argc != 3) {
60 log_error("This program expects two arguments.");
61 return EXIT_FAILURE;
62 }
63
64 type = argv[1];
65 device = argv[2];
66
67 if (stat(device, &st) < 0) {
68 r = log_error_errno(errno, "Failed to stat \"%s\": %m", device);
69 goto finish;
70 }
71
72 if (!S_ISBLK(st.st_mode))
73 log_info("%s is not a block device.", device);
74
75 r = probe_filesystem(device, &detected);
76 if (r < 0) {
77 log_warning_errno(r,
78 r == -EUCLEAN ?
79 "Cannot reliably determine probe \"%s\", refusing to proceed." :
80 "Failed to probe \"%s\": %m",
81 device);
82 goto finish;
83 }
84
85 if (detected) {
86 log_info("%s is not empty (type %s), exiting", device, detected);
87 goto finish;
88 }
89
90 r = makefs(type, device);
91
92 finish:
93 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
94 }