]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: improve ENOSYS fallback
authorKarel Zak <kzak@redhat.com>
Tue, 25 Apr 2023 14:25:14 +0000 (16:25 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 25 Apr 2023 14:25:14 +0000 (16:25 +0200)
In some cases, for example:

 # mount -t foo,bar,ext4 /dev/sdc /mnt/test

libmount calls fsopen() later (after mount preparation stage), but we
need during preparation check if hook_mount.c stuff (new API) is usable.

Let's do it by dummy fsopen() call.

Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/hook_mount.c

index 2dbe5217cc2aac2abb3ce65bc913e7ed94135ef2..9d1ffaf0d157688f2a64569ab0fee75508c29b49 100644 (file)
@@ -496,6 +496,20 @@ static int hook_attach_target(struct libmnt_context *cxt,
        return rc == 0 ? 0 : -errno;
 }
 
+static inline int fsopen_is_supported(void)
+{
+       int dummy, rc = 1;
+
+       errno = 0;
+       dummy = fsopen(NULL, FSOPEN_CLOEXEC);
+
+       if (errno == ENOSYS)
+               rc = 0;
+       if (dummy >= 0)
+               close(dummy);
+       return rc;
+}
+
 /*
  * open_tree() and fsopen()
  */
@@ -547,12 +561,19 @@ static int init_sysapi(struct libmnt_context *cxt,
         *  is called later in hook_create_mount(). */
        } else {
                const char *type = mnt_fs_get_fstype(cxt->fs);
+               int rc = 0;
+
+               /* fsopen() to create a superblock */
+               if (cxt->helper == NULL && type && !strchr(type, ','))
+                       rc = open_fs_configuration_context(cxt, api, type);
 
-               if (mnt_context_is_fake(cxt))
-                       goto fake;
-               if (cxt->helper == NULL
-                   && type && !strchr(type, ',')
-                   && open_fs_configuration_context(cxt, api, type) < 0)
+               /* dummy fsopen() to test if API is available */
+               else if (!fsopen_is_supported()) {
+                       errno = ENOSYS;
+                       rc = -errno;
+                       set_syscall_status(cxt, "fsopen", rc == 0);
+               }
+               if (rc < 0)
                        goto fail;
        }