blob: 8c2a783e9d96998844017549d6abb6f6f747887d [file] [log] [blame] [raw]
Zbigniew Jędrzejewski-Szmekb7f28ac2017-11-26 22:51:29 +01001/***
2 SPDX-License-Identifier: LGPL-2.1+
Zbigniew Jędrzejewski-Szmekb7f28ac2017-11-26 22:51:29 +01003***/
4
5#include <fcntl.h>
6#include <signal.h>
7#include <sys/prctl.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10#include <unistd.h>
11
12#include "alloc-util.h"
13#include "dissect-image.h"
Lennart Poetteringdccca822018-01-11 00:39:12 +010014#include "process-util.h"
Zbigniew Jędrzejewski-Szmekb7f28ac2017-11-26 22:51:29 +010015#include "signal-util.h"
16#include "string-util.h"
17
18static int makefs(const char *type, const char *device) {
19 const char *mkfs;
20 pid_t pid;
Lennart Poettering4c253ed2017-12-22 13:08:14 +010021 int r;
Zbigniew Jędrzejewski-Szmekb7f28ac2017-11-26 22:51:29 +010022
23 if (streq(type, "swap"))
24 mkfs = "/sbin/mkswap";
25 else
26 mkfs = strjoina("/sbin/mkfs.", type);
27 if (access(mkfs, X_OK) != 0)
28 return log_error_errno(errno, "%s is not executable: %m", mkfs);
29
Lennart Poetteringb6e1fff2017-12-27 21:49:19 +010030 r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
Lennart Poettering4c253ed2017-12-22 13:08:14 +010031 if (r < 0)
Lennart Poetteringb6e1fff2017-12-27 21:49:19 +010032 return r;
Lennart Poettering4c253ed2017-12-22 13:08:14 +010033 if (r == 0) {
Zbigniew Jędrzejewski-Szmekb7f28ac2017-11-26 22:51:29 +010034 const char *cmdline[3] = { mkfs, device, NULL };
35
36 /* Child */
Zbigniew Jędrzejewski-Szmekb7f28ac2017-11-26 22:51:29 +010037
38 execv(cmdline[0], (char**) cmdline);
39 _exit(EXIT_FAILURE);
40 }
41
Lennart Poettering7d4904f2017-12-28 00:51:19 +010042 return wait_for_terminate_and_check(mkfs, pid, WAIT_LOG);
Zbigniew Jędrzejewski-Szmekb7f28ac2017-11-26 22:51:29 +010043}
44
45int main(int argc, char *argv[]) {
46 const char *device, *type;
47 _cleanup_free_ char *detected = NULL;
48 struct stat st;
49 int r;
50
51 log_set_target(LOG_TARGET_AUTO);
52 log_parse_environment();
53 log_open();
54
55 if (argc != 3) {
56 log_error("This program expects two arguments.");
57 return EXIT_FAILURE;
58 }
59
60 type = argv[1];
61 device = argv[2];
62
63 if (stat(device, &st) < 0) {
64 r = log_error_errno(errno, "Failed to stat \"%s\": %m", device);
65 goto finish;
66 }
67
68 if (!S_ISBLK(st.st_mode))
69 log_info("%s is not a block device.", device);
70
71 r = probe_filesystem(device, &detected);
72 if (r < 0) {
Zbigniew Jędrzejewski-Szmek7cc84b22017-11-30 12:09:36 +010073 log_warning_errno(r,
74 r == -EUCLEAN ?
75 "Cannot reliably determine probe \"%s\", refusing to proceed." :
76 "Failed to probe \"%s\": %m",
77 device);
Zbigniew Jędrzejewski-Szmekb7f28ac2017-11-26 22:51:29 +010078 goto finish;
79 }
80
81 if (detected) {
82 log_info("%s is not empty (type %s), exiting", device, detected);
83 goto finish;
84 }
85
86 r = makefs(type, device);
87
88finish:
89 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
90}