]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mountpoint-util: Deal with kernel API breakage in "norecovery" mount option
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 17 May 2024 08:46:12 +0000 (10:46 +0200)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 17 May 2024 12:29:09 +0000 (14:29 +0200)
"norecovery" was deprecated for btrfs in
https://github.com/torvalds/linux/commit/74ef00185eb864252156022ff129b01549504175
and removed in
https://github.com/torvalds/linux/commit/a1912f712188291f9d7d434fba155461f1ebef66.

Let's drop our assumption that btrfs supports "norecovery" and first query for the
new name of the option followed by querying for the old name.

src/basic/mountpoint-util.c
src/basic/mountpoint-util.h
src/shared/dissect-image.c
src/test/test-mountpoint-util.c

index 0fb146f0cf1a8a963666167cf21c0a7c79a82cf7..8e0dbb703a5a93664f63f350cf920bc5cfa3be43 100644 (file)
@@ -495,16 +495,30 @@ bool fstype_can_discard(const char *fstype) {
         return mount_option_supported(fstype, "discard", NULL) > 0;
 }
 
-bool fstype_can_norecovery(const char *fstype) {
+const char* fstype_norecovery_option(const char *fstype) {
+        int r;
+
         assert(fstype);
 
         /* Use a curated list as first check, to avoid calling fsopen() which might load kmods, which might
          * not be allowed in our MAC context. */
-        if (STR_IN_SET(fstype, "ext3", "ext4", "xfs", "btrfs"))
-                return true;
+        if (STR_IN_SET(fstype, "ext3", "ext4", "xfs"))
+                return "norecovery";
+
+        /* btrfs dropped support for the "norecovery" option in 6.8
+         * (https://github.com/torvalds/linux/commit/a1912f712188291f9d7d434fba155461f1ebef66) and replaced
+         * it with rescue=nologreplay, so we check for the new name first and fall back to checking for the
+         * old name if the new name doesn't work. */
+        if (streq(fstype, "btrfs")) {
+                r = mount_option_supported(fstype, "rescue=nologreplay", NULL);
+                if (r < 0)
+                        log_debug_errno(r, "Failed to check for btrfs rescue=nologreplay option, assuming it is not supported: %m");
+                if (r > 0)
+                        return "rescue=nologreplay";
+        }
 
         /* On new kernels we can just ask the kernel */
-        return mount_option_supported(fstype, "norecovery", NULL) > 0;
+        return mount_option_supported(fstype, "norecovery", NULL) > 0 ? "norecovery" : NULL;
 }
 
 bool fstype_can_umask(const char *fstype) {
index f867f6c955677586fe3bc845e1c3df68ecc90e0c..d7c6251aff78613e5156a28e50c4da7666751e61 100644 (file)
@@ -57,9 +57,10 @@ bool fstype_is_blockdev_backed(const char *fstype);
 bool fstype_is_ro(const char *fsype);
 bool fstype_can_discard(const char *fstype);
 bool fstype_can_uid_gid(const char *fstype);
-bool fstype_can_norecovery(const char *fstype);
 bool fstype_can_umask(const char *fstype);
 
+const char* fstype_norecovery_option(const char *fstype);
+
 int dev_is_devtmpfs(void);
 
 int mount_fd(const char *source, int target_fd, const char *filesystemtype, unsigned long mountflags, const void *data);
index 471e83b07480b49b09920d5aa234da4e8fd7705c..a9e211f246a1f77bd3bd2006958391e2aa596429 100644 (file)
@@ -1911,9 +1911,12 @@ int partition_pick_mount_options(
          * access that actually modifies stuff work on such image files. Or to say this differently: if
          * people want their file systems to be fixed up they should just open them in writable mode, where
          * all these problems don't exist. */
-        if (!rw && fstype && fstype_can_norecovery(fstype))
-                if (!strextend_with_separator(&options, ",", "norecovery"))
+        if (!rw && fstype) {
+                const char *option = fstype_norecovery_option(fstype);
+
+                if (option && !strextend_with_separator(&options, ",", option))
                         return -ENOMEM;
+        }
 
         if (discard && fstype && fstype_can_discard(fstype))
                 if (!strextend_with_separator(&options, ",", "discard"))
index 6060ec2fc803b3bf7c401e4b39ac0d369db060eb..85c0859a839c3dfcb886d04f9bcdc955228c6799 100644 (file)
@@ -354,9 +354,9 @@ TEST(fstype_can_discard) {
 }
 
 TEST(fstype_can_norecovery) {
-        assert_se(fstype_can_norecovery("ext4"));
-        assert_se(!fstype_can_norecovery("vfat"));
-        assert_se(!fstype_can_norecovery("tmpfs"));
+        ASSERT_STREQ(fstype_norecovery_option("ext4"), "norecovery");
+        ASSERT_NULL(fstype_norecovery_option("vfat"));
+        ASSERT_NULL(fstype_norecovery_option("tmpfs"));
 }
 
 TEST(fstype_can_umask) {