1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <fcntl.h>
4 #include <sys/file.h>
5 #include <sys/prctl.h>
6 #include <sys/stat.h>
7 #include <sys/types.h>
8 #include <unistd.h>
9
10 #include "alloc-util.h"
11 #include "blockdev-util.h"
12 #include "dissect-image.h"
13 #include "fd-util.h"
14 #include "main-func.h"
15 #include "mkfs-util.h"
16 #include "process-util.h"
17 #include "signal-util.h"
18 #include "string-util.h"
19
run(int argc,char * argv[])20 static int run(int argc, char *argv[]) {
21 _cleanup_free_ char *device = NULL, *fstype = NULL, *detected = NULL;
22 _cleanup_close_ int lock_fd = -1;
23 sd_id128_t uuid;
24 struct stat st;
25 int r;
26
27 log_setup();
28
29 if (argc != 3)
30 return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
31 "This program expects two arguments.");
32
33 /* type and device must be copied because makefs calls safe_fork, which clears argv[] */
34 fstype = strdup(argv[1]);
35 if (!fstype)
36 return log_oom();
37
38 device = strdup(argv[2]);
39 if (!device)
40 return log_oom();
41
42 if (stat(device, &st) < 0)
43 return log_error_errno(errno, "Failed to stat \"%s\": %m", device);
44
45 if (S_ISBLK(st.st_mode)) {
46 /* Lock the device so that udev doesn't interfere with our work */
47
48 lock_fd = lock_whole_block_device(st.st_rdev, LOCK_EX);
49 if (lock_fd < 0)
50 return log_error_errno(lock_fd, "Failed to lock whole block device of \"%s\": %m", device);
51 } else
52 log_debug("%s is not a block device, no need to lock.", device);
53
54 r = probe_filesystem(device, &detected);
55 if (r == -EUCLEAN)
56 return log_error_errno(r, "Ambiguous results of probing for file system on \"%s\", refusing to proceed.", device);
57 if (r < 0)
58 return log_error_errno(r, "Failed to probe \"%s\": %m", device);
59 if (detected) {
60 log_info("'%s' is not empty (contains file system of type %s), exiting.", device, detected);
61 return 0;
62 }
63
64 r = sd_id128_randomize(&uuid);
65 if (r < 0)
66 return log_error_errno(r, "Failed to generate UUID for file system: %m");
67
68 return make_filesystem(device, fstype, basename(device), uuid, true);
69 }
70
71 DEFINE_MAIN_FUNCTION(run);
72