]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Add mkfs wrapper which first checks if the partition is empty
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 26 Nov 2017 21:51:29 +0000 (22:51 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 30 Nov 2017 19:46:30 +0000 (20:46 +0100)
meson.build
src/partition/makefs.c [new file with mode: 0644]

index 031776c41f179609330b5f703d3c04405eb84b0b..abb152a03389db837d1a7bdcb87d233979e73c0f 100644 (file)
@@ -1945,6 +1945,14 @@ executable('systemd-growfs',
            install : true,
            install_dir : rootlibexecdir)
 
+executable('systemd-makefs',
+           'src/partition/makefs.c',
+           include_directories : includes,
+           link_with : [libshared],
+           install_rpath : rootlibexecdir,
+           install : true,
+           install_dir : rootlibexecdir)
+
 executable('systemd-sleep',
            'src/sleep/sleep.c',
            include_directories : includes,
diff --git a/src/partition/makefs.c b/src/partition/makefs.c
new file mode 100644 (file)
index 0000000..c24c6eb
--- /dev/null
@@ -0,0 +1,106 @@
+/***
+  SPDX-License-Identifier: LGPL-2.1+
+
+  This file is part of systemd.
+
+  Copyright 2017 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/prctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "alloc-util.h"
+#include "dissect-image.h"
+#include "signal-util.h"
+#include "string-util.h"
+
+static int makefs(const char *type, const char *device) {
+        const char *mkfs;
+        pid_t pid;
+
+        if (streq(type, "swap"))
+                mkfs = "/sbin/mkswap";
+        else
+                mkfs = strjoina("/sbin/mkfs.", type);
+        if (access(mkfs, X_OK) != 0)
+                return log_error_errno(errno, "%s is not executable: %m", mkfs);
+
+        pid = fork();
+        if (pid < 0)
+                return log_error_errno(errno, "fork(): %m");
+
+        if (pid == 0) {
+                const char *cmdline[3] = { mkfs, device, NULL };
+
+                /* Child */
+
+                (void) reset_all_signal_handlers();
+                (void) reset_signal_mask();
+                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
+
+                execv(cmdline[0], (char**) cmdline);
+                _exit(EXIT_FAILURE);
+        }
+
+        return wait_for_terminate_and_warn(mkfs, pid, true);
+}
+
+int main(int argc, char *argv[]) {
+        const char *device, *type;
+        _cleanup_free_ char *detected = NULL;
+        struct stat st;
+        int r;
+
+        log_set_target(LOG_TARGET_AUTO);
+        log_parse_environment();
+        log_open();
+
+        if (argc != 3) {
+                log_error("This program expects two arguments.");
+                return EXIT_FAILURE;
+        }
+
+        type = argv[1];
+        device = argv[2];
+
+        if (stat(device, &st) < 0) {
+                r = log_error_errno(errno, "Failed to stat \"%s\": %m", device);
+                goto finish;
+        }
+
+        if (!S_ISBLK(st.st_mode))
+                log_info("%s is not a block device.", device);
+
+        r = probe_filesystem(device, &detected);
+        if (r < 0) {
+                log_warning_errno(r, "Failed to probe \"%s\": %m", device);
+                goto finish;
+        }
+
+        if (detected) {
+                log_info("%s is not empty (type %s), exiting", device, detected);
+                goto finish;
+        }
+
+        r = makefs(type, device);
+
+finish:
+        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}