summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-07-29 18:36:26 +0200
committerLennart Poettering <lennart@poettering.net>2020-08-24 21:59:49 +0200
commitc95f9a2351ffd63b53a4c33fb683606e43677c89 (patch)
treed1210cb74c8e96a25e60a184e6da3ed0479a600d
parent8dbc208cc1a7bbd9af44d98df4a4eb472266699a (diff)
downloadsystemd-c95f9a2351ffd63b53a4c33fb683606e43677c89.tar.gz
shared: introduce mkfs-util.c/.h
Let's move the "mkfs" code from homed there, plus other related code. This way we can easily reuse it from other places.
-rw-r--r--src/basic/path-util.c12
-rw-r--r--src/basic/path-util.h1
-rw-r--r--src/home/homework-luks.c68
-rw-r--r--src/shared/meson.build2
-rw-r--r--src/shared/mkfs-util.c114
-rw-r--r--src/shared/mkfs-util.h10
6 files changed, 128 insertions, 79 deletions
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index c4e022b3a1..c463ae23ab 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -726,18 +726,6 @@ int fsck_exists(const char *fstype) {
return binary_is_good(checker);
}
-int mkfs_exists(const char *fstype) {
- const char *mkfs;
-
- assert(fstype);
-
- if (streq(fstype, "auto"))
- return -EINVAL;
-
- mkfs = strjoina("mkfs.", fstype);
- return binary_is_good(mkfs);
-}
-
int parse_path_argument_and_warn(const char *path, bool suppress_root, char **arg) {
char *p;
int r;
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
index 30031fca8e..99c4e35782 100644
--- a/src/basic/path-util.h
+++ b/src/basic/path-util.h
@@ -85,7 +85,6 @@ int find_binary(const char *name, char **filename);
bool paths_check_timestamp(const char* const* paths, usec_t *paths_ts_usec, bool update);
int fsck_exists(const char *fstype);
-int mkfs_exists(const char *fstype);
/* Iterates through the path prefixes of the specified path, going up
* the tree, to root. Also returns "" (and not "/"!) for the root
diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c
index 1fcf17806e..1fe0465cfb 100644
--- a/src/home/homework-luks.c
+++ b/src/home/homework-luks.c
@@ -24,6 +24,7 @@
#include "memory-util.h"
#include "missing_magic.h"
#include "mkdir.h"
+#include "mkfs-util.h"
#include "mount-util.h"
#include "openssl-util.h"
#include "parse-util.h"
@@ -1371,71 +1372,6 @@ int home_trim_luks(UserRecord *h) {
return 0;
}
-static int run_mkfs(
- const char *node,
- const char *fstype,
- const char *label,
- sd_id128_t uuid,
- bool discard) {
-
- int r;
-
- assert(node);
- assert(fstype);
- assert(label);
-
- r = mkfs_exists(fstype);
- if (r < 0)
- return log_error_errno(r, "Failed to check if mkfs for file system %s exists: %m", fstype);
- if (r == 0)
- return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "No mkfs for file system %s installed.", fstype);
-
- r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR, NULL);
- if (r < 0)
- return r;
- if (r == 0) {
- const char *mkfs;
- char suuid[37];
-
- /* Child */
-
- mkfs = strjoina("mkfs.", fstype);
- id128_to_uuid_string(uuid, suuid);
-
- if (streq(fstype, "ext4"))
- execlp(mkfs, mkfs,
- "-L", label,
- "-U", suuid,
- "-I", "256",
- "-O", "has_journal",
- "-m", "0",
- "-E", discard ? "lazy_itable_init=1,discard" : "lazy_itable_init=1,nodiscard",
- node, NULL);
- else if (streq(fstype, "btrfs")) {
- if (discard)
- execlp(mkfs, mkfs, "-L", label, "-U", suuid, node, NULL);
- else
- execlp(mkfs, mkfs, "-L", label, "-U", suuid, "--nodiscard", node, NULL);
- } else if (streq(fstype, "xfs")) {
- const char *j;
-
- j = strjoina("uuid=", suuid);
- if (discard)
- execlp(mkfs, mkfs, "-L", label, "-m", j, "-m", "reflink=1", node, NULL);
- else
- execlp(mkfs, mkfs, "-L", label, "-m", j, "-m", "reflink=1", "-K", node, NULL);
- } else {
- log_error("Cannot make file system: %s", fstype);
- _exit(EXIT_FAILURE);
- }
-
- log_error_errno(errno, "Failed to execute %s: %m", mkfs);
- _exit(EXIT_FAILURE);
- }
-
- return 0;
-}
-
static struct crypt_pbkdf_type* build_good_pbkdf(struct crypt_pbkdf_type *buffer, UserRecord *hr) {
assert(buffer);
assert(hr);
@@ -2083,7 +2019,7 @@ int home_create_luks(
log_info("Setting up LUKS device %s completed.", dm_node);
- r = run_mkfs(dm_node, fstype, user_record_user_name_and_realm(h), fs_uuid, user_record_luks_discard(h));
+ r = make_filesystem(dm_node, fstype, user_record_user_name_and_realm(h), fs_uuid, user_record_luks_discard(h));
if (r < 0)
goto fail;
diff --git a/src/shared/meson.build b/src/shared/meson.build
index d192a4d8d7..39bf5523d6 100644
--- a/src/shared/meson.build
+++ b/src/shared/meson.build
@@ -166,6 +166,8 @@ shared_sources = files('''
macvlan-util.c
macvlan-util.h
main-func.h
+ mkfs-util.c
+ mkfs-util.h
module-util.h
mount-util.c
mount-util.h
diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c
new file mode 100644
index 0000000000..a78f68e398
--- /dev/null
+++ b/src/shared/mkfs-util.c
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "id128-util.h"
+#include "mkfs-util.h"
+#include "path-util.h"
+#include "process-util.h"
+#include "string-util.h"
+
+int mkfs_exists(const char *fstype) {
+ const char *mkfs;
+ int r;
+
+ assert(fstype);
+
+ if (STR_IN_SET(fstype, "auto", "swap")) /* these aren't real file system types, refuse early */
+ return -EINVAL;
+
+ mkfs = strjoina("mkfs.", fstype);
+ if (!filename_is_valid(mkfs)) /* refuse file system types with slashes and similar */
+ return -EINVAL;
+
+ r = find_binary(mkfs, NULL);
+ if (r == -ENOENT)
+ return false;
+ if (r < 0)
+ return r;
+
+ return true;
+}
+
+int make_filesystem(
+ const char *node,
+ const char *fstype,
+ const char *label,
+ sd_id128_t uuid,
+ bool discard) {
+
+ _cleanup_free_ char *mkfs = NULL;
+ int r;
+
+ assert(node);
+ assert(fstype);
+ assert(label);
+
+ if (streq(fstype, "swap")) {
+ r = find_binary("mkswap", &mkfs);
+ if (r == -ENOENT)
+ return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "mkswap binary not available.");
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine whether mkswap binary exists: %m");
+ } else {
+ r = mkfs_exists(fstype);
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine whether mkfs binary for %s exists: %m", fstype);
+ if (r == 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EPROTONOSUPPORT), "mkfs binary for %s is not available.", fstype);
+
+ mkfs = strjoin("mkfs.", fstype);
+ if (!mkfs)
+ return log_oom();
+ }
+
+ r = safe_fork("(mkfs)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR, NULL);
+ if (r < 0)
+ return r;
+ if (r == 0) {
+ char suuid[ID128_UUID_STRING_MAX];
+
+ /* Child */
+ id128_to_uuid_string(uuid, suuid);
+
+ if (streq(fstype, "ext4"))
+ (void) execlp(mkfs, mkfs,
+ "-L", label,
+ "-U", suuid,
+ "-I", "256",
+ "-O", "has_journal",
+ "-m", "0",
+ "-E", discard ? "lazy_itable_init=1,discard" : "lazy_itable_init=1,nodiscard",
+ node, NULL);
+
+ else if (streq(fstype, "btrfs")) {
+ if (discard)
+ (void) execlp(mkfs, mkfs, "-L", label, "-U", suuid, node, NULL);
+ else
+ (void) execlp(mkfs, mkfs, "-L", label, "-U", suuid, "--nodiscard", node, NULL);
+
+ } else if (streq(fstype, "xfs")) {
+ const char *j;
+
+ j = strjoina("uuid=", suuid);
+ if (discard)
+ (void) execlp(mkfs, mkfs, "-L", label, "-m", j, "-m", "reflink=1", node, NULL);
+ else
+ (void) execlp(mkfs, mkfs, "-L", label, "-m", j, "-m", "reflink=1", "-K", node, NULL);
+
+ } else if (streq(fstype, "swap")) {
+
+ (void) execlp(mkfs, mkfs,
+ "-L", label,
+ "-U", suuid,
+ node, NULL);
+
+ } else
+ /* Generic fallback for all other file systems */
+ (void) execlp(mkfs, mkfs, node, NULL);
+
+ log_error_errno(errno, "Failed to execute %s: %m", mkfs);
+
+ _exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
diff --git a/src/shared/mkfs-util.h b/src/shared/mkfs-util.h
new file mode 100644
index 0000000000..54e9b931e6
--- /dev/null
+++ b/src/shared/mkfs-util.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include <stdbool.h>
+
+#include "sd-id128.h"
+
+int mkfs_exists(const char *fstype);
+
+int make_filesystem(const char *node, const char *fstype, const char *label, sd_id128_t uuid, bool discard);