From 44cdeb6e33d8d2c9f32e1c46ce402d5311ae6a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 8 Nov 2021 12:12:58 +0100 Subject: [PATCH 01/10] makefs: reindent mkfs calls to follow the same style I think this also makes it much easier to see what args are passed. --- src/shared/mkfs-util.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index 924afdfd93..b9c2f147bc 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -75,23 +75,29 @@ int make_filesystem( "-I", "256", "-O", "has_journal", "-m", "0", - "-E", discard ? "lazy_itable_init=1,discard" : "lazy_itable_init=1,nodiscard", + "-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1", node, NULL); else if (streq(fstype, "btrfs")) { - if (discard) - (void) execlp(mkfs, mkfs, "-L", label, "-U", ID128_TO_UUID_STRING(uuid), node, NULL); - else - (void) execlp(mkfs, mkfs, "-L", label, "-U", ID128_TO_UUID_STRING(uuid), "--nodiscard", node, NULL); + (void) execlp(mkfs, mkfs, + "-L", label, + "-U", ID128_TO_UUID_STRING(uuid), + node, + discard ? NULL : "--nodiscard", + NULL); } else if (streq(fstype, "xfs")) { const char *j; j = strjoina("uuid=", ID128_TO_UUID_STRING(uuid)); - 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); + + (void) execlp(mkfs, mkfs, + "-L", label, + "-m", j, + "-m", "reflink=1", + node, + discard ? NULL : "-K", + NULL); } else if (streq(fstype, "vfat")) { char mangled_label[8 + 3 + 1], vol_id[8 + 1]; From 8e93a614e7c20ee28f1d3b4aa51c0e4200aa2c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Mon, 8 Nov 2021 12:18:30 +0100 Subject: [PATCH 02/10] makefs: also set uuid/label for ext2/ext3 We were only "supporting" ext4. Let's add "support", i.e. pass our optimization options and uuid/label for the other two fses in the same family. Nowadays there is separate code in the kernel, all three fs types are handled by ext4 code. ext2 in particular is useful for in-memory devices: the journal is just a waste of space there. ext3 is added for completeness mostly, since ext4 should probably be used instead. But people might use it for testing or for compatibility with older systems and I don't see much reason to not add "support" here. --- src/shared/mkfs-util.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index b9c2f147bc..1056de1bec 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -68,7 +68,16 @@ int make_filesystem( return r; if (r == 0) { /* Child */ - if (streq(fstype, "ext4")) + if (streq(fstype, "ext2")) + (void) execlp(mkfs, mkfs, + "-L", label, + "-U", ID128_TO_UUID_STRING(uuid), + "-I", "256", + "-m", "0", + "-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1", + node, NULL); + + else if (STR_IN_SET(fstype, "ext3", "ext4")) (void) execlp(mkfs, mkfs, "-L", label, "-U", ID128_TO_UUID_STRING(uuid), From 4f05a11c553580b370f9884f66b01ecfbd9f56a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 9 Nov 2021 08:40:24 +0100 Subject: [PATCH 03/10] makefs: supress mkfs output, but print one line on success $ for i in ext2 ext3 ext4 btrfs xfs vfat swap minix; do echo $i && wipefs -q -a /var/tmp/test2_img && build/systemd-makefs $i /var/tmp/test2_img done ext2 /var/tmp/test2_img successfully formatted as ext2 (label "test2_img", uuid ad584a5b-037b-497a-825d-eaf2ba90da2d) ext3 /var/tmp/test2_img successfully formatted as ext3 (label "test2_img", uuid 95239fff-55f4-44d5-bae0-11ef75d13166) ext4 /var/tmp/test2_img successfully formatted as ext4 (label "test2_img", uuid 8c7ea699-05ab-4ce6-8df6-bc20d53dfd29) btrfs /var/tmp/test2_img successfully formatted as btrfs (label "test2_img", uuid 860bb061-4d92-4607-8821-a9d00216490e) xfs /var/tmp/test2_img successfully formatted as xfs (label "test2_img", uuid f32499ea-7311-47bb-be57-da62e51d33ae) vfat mkfs.fat 4.2 (2021-01-31) /var/tmp/test2_img successfully formatted as vfat (label "TEST2_IMG", uuid d1e4ae63) swap mkswap: /var/tmp/test2_img: insecure permissions 0644, fix with: chmod 0600 /var/tmp/test2_img mkswap: /var/tmp/test2_img contains holes or other unsupported extents. This swap file can be rejected by kernel on swap activation! Use --verbose for more details. Setting up swapspace version 1, size = 256 MiB (268431360 bytes) LABEL=test2_img, UUID=16bc3d8c-98d4-462b-8ff8-338467cde871 /var/tmp/test2_img successfully formatted as swap (no label or uuid specified) minix 21856 inodes 65535 blocks Firstdatazone=696 (696) Zonesize=1024 Maxsize=268966912 /var/tmp/test2_img successfully formatted as minix (no label or uuid specified) --- src/partition/makefs.c | 2 +- src/shared/mkfs-util.c | 64 ++++++++++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/partition/makefs.c b/src/partition/makefs.c index 7c94fbfedb..b6979b7e4f 100644 --- a/src/partition/makefs.c +++ b/src/partition/makefs.c @@ -49,7 +49,7 @@ static int run(int argc, char *argv[]) { if (lock_fd < 0) return log_error_errno(lock_fd, "Failed to lock whole block device of \"%s\": %m", device); } else - log_info("%s is not a block device.", device); + log_debug("%s is not a block device, no need to lock.", device); r = probe_filesystem(device, &detected); if (r == -EUCLEAN) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index 1056de1bec..fbf04aa7ae 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -39,6 +39,8 @@ int make_filesystem( bool discard) { _cleanup_free_ char *mkfs = NULL; + char mangled_label[8 + 3 + 1], + vol_id[CONST_MAX(ID128_UUID_STRING_MAX, 8 + 1)] = {}; int r; assert(node); @@ -63,15 +65,35 @@ int make_filesystem( return log_oom(); } + if (streq(fstype, "vfat")) { + /* Classic FAT only allows 11 character uppercase labels */ + strncpy(mangled_label, label, sizeof(mangled_label)-1); + mangled_label[sizeof(mangled_label)-1] = 0; + ascii_strupper(mangled_label); + label = mangled_label; + + xsprintf(vol_id, "%08" PRIx32, + ((uint32_t) uuid.bytes[0] << 24) | + ((uint32_t) uuid.bytes[1] << 16) | + ((uint32_t) uuid.bytes[2] << 8) | + ((uint32_t) uuid.bytes[3])); /* Take first 32 bytes of UUID */ + } + + if (isempty(vol_id)) + id128_to_uuid_string(uuid, vol_id); + 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) { /* Child */ + + /* When changing this conditional, also adjust the log statement below. */ if (streq(fstype, "ext2")) (void) execlp(mkfs, mkfs, + "-q", "-L", label, - "-U", ID128_TO_UUID_STRING(uuid), + "-U", vol_id, "-I", "256", "-m", "0", "-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1", @@ -79,8 +101,9 @@ int make_filesystem( else if (STR_IN_SET(fstype, "ext3", "ext4")) (void) execlp(mkfs, mkfs, + "-q", "-L", label, - "-U", ID128_TO_UUID_STRING(uuid), + "-U", vol_id, "-I", "256", "-O", "has_journal", "-m", "0", @@ -89,8 +112,9 @@ int make_filesystem( else if (streq(fstype, "btrfs")) { (void) execlp(mkfs, mkfs, + "-q", "-L", label, - "-U", ID128_TO_UUID_STRING(uuid), + "-U", vol_id, node, discard ? NULL : "--nodiscard", NULL); @@ -98,9 +122,10 @@ int make_filesystem( } else if (streq(fstype, "xfs")) { const char *j; - j = strjoina("uuid=", ID128_TO_UUID_STRING(uuid)); + j = strjoina("uuid=", vol_id); (void) execlp(mkfs, mkfs, + "-q", "-L", label, "-m", j, "-m", "reflink=1", @@ -108,34 +133,24 @@ int make_filesystem( discard ? NULL : "-K", NULL); - } else if (streq(fstype, "vfat")) { - char mangled_label[8 + 3 + 1], vol_id[8 + 1]; - - /* Classic FAT only allows 11 character uppercase labels */ - strncpy(mangled_label, label, sizeof(mangled_label)-1); - mangled_label[sizeof(mangled_label)-1] = 0; - ascii_strupper(mangled_label); - - xsprintf(vol_id, "%08" PRIx32, - ((uint32_t) uuid.bytes[0] << 24) | - ((uint32_t) uuid.bytes[1] << 16) | - ((uint32_t) uuid.bytes[2] << 8) | - ((uint32_t) uuid.bytes[3])); /* Take first 32 byte of UUID */ + } else if (streq(fstype, "vfat")) (void) execlp(mkfs, mkfs, "-i", vol_id, - "-n", mangled_label, + "-n", label, "-F", "32", /* yes, we force FAT32 here */ node, NULL); - } else if (streq(fstype, "swap")) { + else if (streq(fstype, "swap")) + /* TODO: add --quiet here if + * https://github.com/util-linux/util-linux/issues/1499 resolved. */ (void) execlp(mkfs, mkfs, "-L", label, - "-U", ID128_TO_UUID_STRING(uuid), + "-U", vol_id, node, NULL); - } else + else /* Generic fallback for all other file systems */ (void) execlp(mkfs, mkfs, node, NULL); @@ -144,5 +159,12 @@ int make_filesystem( _exit(EXIT_FAILURE); } + if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "btrfs", "xfs", "vfat", "swap")) + log_info("%s successfully formatted as %s (label \"%s\", uuid %s)", + node, fstype, label, vol_id); + else + log_info("%s successfully formatted as %s (no label or uuid specified)", + node, fstype); + return 0; } From a456086b376b4e845b8049e13a500b2f3001dd38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 12 Nov 2021 09:31:55 +0100 Subject: [PATCH 04/10] basic/utf8: inline some iterator variables --- src/basic/utf8.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/basic/utf8.c b/src/basic/utf8.c index 63fc9f71d1..2ad2151816 100644 --- a/src/basic/utf8.c +++ b/src/basic/utf8.c @@ -124,11 +124,9 @@ int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) { } bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) { - const char *p; - assert(str); - for (p = str; length > 0;) { + for (const char *p = str; length > 0;) { int encoded_len, r; char32_t val; @@ -289,14 +287,12 @@ char *utf8_escape_non_printable_full(const char *str, size_t console_width, bool } char *ascii_is_valid(const char *str) { - const char *p; - /* Check whether the string consists of valid ASCII bytes, * i.e values between 0 and 127, inclusive. */ assert(str); - for (p = str; *p; p++) + for (const char *p = str; *p; p++) if ((unsigned char) *p >= 128) return NULL; From 9b49a3b49e78fa46ab5da45e5a176bab3df5803a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 12 Nov 2021 10:27:13 +0100 Subject: [PATCH 05/10] basic/utf8: add function to convert to ASCII The conversion must be lossy because ASCII doesn't have enough chars. --- src/basic/utf8.c | 31 +++++++++++++++++++++++++++++++ src/basic/utf8.h | 2 ++ src/test/test-utf8.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/src/basic/utf8.c b/src/basic/utf8.c index 2ad2151816..2532fcf81a 100644 --- a/src/basic/utf8.c +++ b/src/basic/utf8.c @@ -312,6 +312,37 @@ char *ascii_is_valid_n(const char *str, size_t len) { return (char*) str; } +int utf8_to_ascii(const char *str, char replacement_char, char **ret) { + /* Convert to a string that has only ASCII chars, replacing anything that is not ASCII + * by replacement_char. */ + + _cleanup_free_ char *ans = new(char, strlen(str) + 1); + if (!ans) + return -ENOMEM; + + char *q = ans; + + for (const char *p = str; *p; q++) { + int l; + + l = utf8_encoded_valid_unichar(p, SIZE_MAX); + if (l < 0) /* Non-UTF-8, let's not even try to propagate the garbage */ + return l; + + if (l == 1) + *q = *p; + else + /* non-ASCII, we need to replace it */ + *q = replacement_char; + + p += l; + } + *q = '\0'; + + *ret = TAKE_PTR(ans); + return 0; +} + /** * utf8_encode_unichar() - Encode single UCS-4 character as UTF-8 * @out_utf8: output buffer of at least 4 bytes or NULL diff --git a/src/basic/utf8.h b/src/basic/utf8.h index b0e969f655..4a06dd62c5 100644 --- a/src/basic/utf8.h +++ b/src/basic/utf8.h @@ -21,6 +21,8 @@ static inline char *utf8_is_valid(const char *s) { char *ascii_is_valid(const char *s) _pure_; char *ascii_is_valid_n(const char *str, size_t len); +int utf8_to_ascii(const char *str, char replacement_char, char **ret); + bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) _pure_; #define utf8_is_printable(str, length) utf8_is_printable_newline(str, length, true) diff --git a/src/test/test-utf8.c b/src/test/test-utf8.c index 4ba9ca8439..763d17ce9e 100644 --- a/src/test/test-utf8.c +++ b/src/test/test-utf8.c @@ -66,6 +66,33 @@ static void test_ascii_is_valid_n(void) { assert_se( ascii_is_valid_n("\342\204\242", 0)); } +static void test_utf8_to_ascii_one(const char *s, int r_expected, const char *expected) { + _cleanup_free_ char *ans = NULL; + int r; + + r = utf8_to_ascii(s, '*', &ans); + log_debug("\"%s\" → %d/\"%s\" (expected %d/\"%s\")", s, r, strnull(ans), r_expected, strnull(expected)); + assert_se(r == r_expected); + assert_se(streq_ptr(ans, expected)); +} + +static void test_utf8_to_ascii(void) { + log_info("/* %s */", __func__); + + test_utf8_to_ascii_one("asdf", 0, "asdf"); + test_utf8_to_ascii_one("dąb", 0, "d*b"); + test_utf8_to_ascii_one("żęśłą óźń", 0, "***** ***"); + test_utf8_to_ascii_one("\342\204\242", 0, "*"); + test_utf8_to_ascii_one("\342\204", -EINVAL, NULL); /* truncated */ + test_utf8_to_ascii_one("\342", -EINVAL, NULL); /* truncated */ + test_utf8_to_ascii_one("\302\256", 0, "*"); + test_utf8_to_ascii_one("", 0, ""); + test_utf8_to_ascii_one(" ", 0, " "); + test_utf8_to_ascii_one("\t", 0, "\t"); + test_utf8_to_ascii_one("串", 0, "*"); + test_utf8_to_ascii_one("…👊🔪💐…", 0, "*****"); +} + static void test_utf8_encoded_valid_unichar(void) { log_info("/* %s */", __func__); @@ -241,6 +268,7 @@ int main(int argc, char *argv[]) { test_utf8_is_printable(); test_ascii_is_valid(); test_ascii_is_valid_n(); + test_utf8_to_ascii(); test_utf8_encoded_valid_unichar(); test_utf8_escape_invalid(); test_utf8_escape_non_printable(); From dc91c971bf1ef0cb3eda77d56f4c18c5631c97e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 9 Nov 2021 08:52:19 +0100 Subject: [PATCH 06/10] makefs: fix label for vfat filesystems I was testing with a "test1.img" and mkfs.vfat rejects "TEST1.IMG" with the error "Labels with characters *?.,;:/\|+=<>[]" are not allowed". So let's replace those characters with "_". --- src/shared/mkfs-util.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index fbf04aa7ae..db755095ee 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -8,6 +8,7 @@ #include "process-util.h" #include "stdio-util.h" #include "string-util.h" +#include "utf8.h" int mkfs_exists(const char *fstype) { const char *mkfs; @@ -31,6 +32,30 @@ int mkfs_exists(const char *fstype) { return true; } +static int mangle_fat_label(const char *s, char **ret) { + assert(s); + + _cleanup_free_ char *q = NULL; + int r; + + r = utf8_to_ascii(s, '_', &q); + if (r < 0) + return r; + + /* Classic FAT only allows 11 character uppercase labels */ + strshorten(q, 11); + ascii_strupper(q); + + /* mkfs.vfat: Labels with characters *?.,;:/\|+=<>[]" are not allowed. + * Let's also replace any control chars. */ + for (char *p = q; *p; p++) + if (strchr("*?.,;:/\\|+=<>[]\"", *p) || char_is_cc(*p)) + *p = '_'; + + *ret = TAKE_PTR(q); + return 0; +} + int make_filesystem( const char *node, const char *fstype, @@ -38,9 +63,8 @@ int make_filesystem( sd_id128_t uuid, bool discard) { - _cleanup_free_ char *mkfs = NULL; - char mangled_label[8 + 3 + 1], - vol_id[CONST_MAX(ID128_UUID_STRING_MAX, 8 + 1)] = {}; + _cleanup_free_ char *mkfs = NULL, *mangled_label = NULL; + char vol_id[CONST_MAX(ID128_UUID_STRING_MAX, 8 + 1)] = {}; int r; assert(node); @@ -66,10 +90,9 @@ int make_filesystem( } if (streq(fstype, "vfat")) { - /* Classic FAT only allows 11 character uppercase labels */ - strncpy(mangled_label, label, sizeof(mangled_label)-1); - mangled_label[sizeof(mangled_label)-1] = 0; - ascii_strupper(mangled_label); + r = mangle_fat_label(label, &mangled_label); + if (r < 0) + return log_error_errno(r, "Failed to determine FAT label from string \"%s\": %m", label); label = mangled_label; xsprintf(vol_id, "%08" PRIx32, From 7ffe593b792653edf220dff893a02d2266959a76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 12 Nov 2021 14:22:58 +0100 Subject: [PATCH 07/10] makefs: fix too-long ext2/3/4 labels --- src/shared/mkfs-util.c | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index db755095ee..f67d7475a0 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -32,6 +32,36 @@ int mkfs_exists(const char *fstype) { return true; } +static int mangle_linux_fs_label(const char *s, size_t max_len, char **ret) { + /* Not more than max_len bytes (12 or 16) */ + + assert(s); + assert(max_len > 0); + assert(ret); + + const char *q; + char *ans; + + for (q = s; *q;) { + int l; + + l = utf8_encoded_valid_unichar(q, SIZE_MAX); + if (l < 0) + return l; + + if ((size_t) (q - s + l) > max_len) + break; + q += l; + } + + ans = memdup_suffix0(s, q - s); + if (!ans) + return -ENOMEM; + + *ret = ans; + return 0; +} + static int mangle_fat_label(const char *s, char **ret) { assert(s); @@ -89,7 +119,13 @@ int make_filesystem( return log_oom(); } - if (streq(fstype, "vfat")) { + if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "xfs")) { + r = mangle_linux_fs_label(label, streq(fstype, "xfs") ? 12 : 16, &mangled_label); + if (r < 0) + return log_error_errno(r, "Failed to determine fs label from string \"%s\": %m", label); + label = mangled_label; + + } else if (streq(fstype, "vfat")) { r = mangle_fat_label(label, &mangled_label); if (r < 0) return log_error_errno(r, "Failed to determine FAT label from string \"%s\": %m", label); From 8d433a99a414adfc6785fd892b0349847f9488b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 12 Nov 2021 15:56:56 +0100 Subject: [PATCH 08/10] makefs: fix too-long swap labels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Apparently mkswap has it's own limit, and it seems to be one lower than the one for ext2/3/4. $ for i in ext2 ext3 ext4 btrfs xfs vfat swap minix; do echo $i && wipefs -q -a '/var/tmp/głąbźśńćąśððð.img' build/systemd-makefs $i '/var/tmp/głąbźśńćąśððð.img' done ext2 /var/tmp/głąbźśńćąśððð.img successfully formatted as ext2 (label "głąbźśńćą", uuid 7626bc5c-8ac4-43cf-87b7-1b2761272dd3) ext3 /var/tmp/głąbźśńćąśððð.img successfully formatted as ext3 (label "głąbźśńćą", uuid 0da22cad-0dbf-4a7a-962d-12cd39d006b5) ext4 /var/tmp/głąbźśńćąśððð.img successfully formatted as ext4 (label "głąbźśńćą", uuid dded267b-8955-4d19-82a5-1f231d446059) btrfs /var/tmp/głąbźśńćąśððð.img successfully formatted as btrfs (label "głąbźśńćąśððð.img", uuid 9e2e89f1-010d-4ab6-80f3-f9e215dbc225) xfs /var/tmp/głąbźśńćąśððð.img successfully formatted as xfs (label "głąbźśń", uuid 2cc937af-4c41-465c-8f52-aab2304bd860) vfat mkfs.fat 4.2 (2021-01-31) /var/tmp/głąbźśńćąśððð.img successfully formatted as vfat (label "G__B_______", uuid a3a9e028) swap ... LABEL=głąbźśńć, UUID=0ab787aa-37a6-4b32-978b-d71efc6e6098 /var/tmp/głąbźśńćąśððð.img successfully formatted as swap (label "głąbźśńć", uuid 0ab787aa-37a6-4b32-978b-d71efc6e6098) minix ... /var/tmp/głąbźśńćąśððð.img successfully formatted as minix (no label or uuid specified) --- src/shared/mkfs-util.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index f67d7475a0..de03cd3c7d 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -119,10 +119,15 @@ int make_filesystem( return log_oom(); } - if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "xfs")) { - r = mangle_linux_fs_label(label, streq(fstype, "xfs") ? 12 : 16, &mangled_label); + if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "xfs", "swap")) { + size_t max_len = + streq(fstype, "xfs") ? 12 : + streq(fstype, "swap") ? 15 : + 16; + + r = mangle_linux_fs_label(label, max_len, &mangled_label); if (r < 0) - return log_error_errno(r, "Failed to determine fs label from string \"%s\": %m", label); + return log_error_errno(r, "Failed to determine volume label from string \"%s\": %m", label); label = mangled_label; } else if (streq(fstype, "vfat")) { From 2d96440fd551b3c037369857b6c0a26e931144d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 13 Nov 2021 16:40:46 +0100 Subject: [PATCH 09/10] makefs: add "support" for f2fs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The man page doesn't quite match what --help says, and I needed to use "-f" to write a wiped partition. This all feels a bit experimental, but the fs has some adherents, and we should make it easy to use. (Also, an empty 256MB device formatted and mounted shows up as Filesystem Size Used Avail Use% Mounted on /dev/loop0 254M 85M 170M 34% /var/tmp/mount which also seems a bit over the top…) Requested in https://github.com/systemd/systemd/pull/21275#issuecomment-967928690. --- src/shared/mkfs-util.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/shared/mkfs-util.c b/src/shared/mkfs-util.c index de03cd3c7d..061a2c2ef7 100644 --- a/src/shared/mkfs-util.c +++ b/src/shared/mkfs-util.c @@ -183,6 +183,17 @@ int make_filesystem( discard ? NULL : "--nodiscard", NULL); + } else if (streq(fstype, "f2fs")) { + (void) execlp(mkfs, mkfs, + "-q", + "-g", /* "default options" */ + "-f", /* force override, without this it doesn't seem to want to write to an empty partition */ + "-l", label, + "-U", vol_id, + "-t", one_zero(discard), + node, + NULL); + } else if (streq(fstype, "xfs")) { const char *j; @@ -223,7 +234,7 @@ int make_filesystem( _exit(EXIT_FAILURE); } - if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "btrfs", "xfs", "vfat", "swap")) + if (STR_IN_SET(fstype, "ext2", "ext3", "ext4", "btrfs", "f2fs", "xfs", "vfat", "swap")) log_info("%s successfully formatted as %s (label \"%s\", uuid %s)", node, fstype, label, vol_id); else From 1c271d3871ac6a47474854cc9676326683e0a45c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Sat, 13 Nov 2021 16:47:40 +0100 Subject: [PATCH 10/10] man: document fs types known to makefs --- man/systemd-makefs@.service.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/man/systemd-makefs@.service.xml b/man/systemd-makefs@.service.xml index 5ea200cc5c..59c1a14394 100644 --- a/man/systemd-makefs@.service.xml +++ b/man/systemd-makefs@.service.xml @@ -52,7 +52,12 @@ systems and swap devices, and after checking that the block device does not already contain a file system or other content, it will execute binaries specific to each filesystem type (/sbin/mkfs.type - or /sbin/mkswap). + or /sbin/mkswap). For certain file system types (currently + ext2/ext3/ext45, + btrfs5, + xfs5, + f2fs, vfat) and for swap devices, it will configure reasonable defaults and set + the file system label and UUID based on the device name. systemd-growfs knows very little about specific file systems and swap devices, and will instruct the kernel to grow the mounted