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