]> granicus.if.org Git - zfs/commitdiff
Let zfs mount all tolerate in-progress mounts
authorDon Brady <don.brady@delphix.com>
Sat, 22 Jun 2019 23:41:21 +0000 (16:41 -0700)
committerTony Hutter <hutter2@llnl.gov>
Wed, 25 Sep 2019 18:27:48 +0000 (11:27 -0700)
The zfs-mount service can unexpectedly fail to start when zfs
encounters a mount that is in progress. This service uses
zfs mount -a, which has a window between the time it checks if
the dataset was mounted and when the actual mount (via mount.zfs
binary) occurs.

The reason for the racing mounts is that both zfs-mount.target
and zfs-share.target are allowed to execute concurrently after
the import.  This is more of an issue with the relatively recent
addition of parallel mounting, and we should consider serializing
the mount and share targets.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Reviewed-by: Allan Jude <allanjude@freebsd.org>
Signed-off-by: Don Brady <don.brady@delphix.com>
Closes #8881

cmd/zfs/zfs_main.c

index 214a437c5dd1465a541be864c11b6d99590231e7..0742160552279af55b667b97c15522d4d271dfe1 100644 (file)
@@ -6446,8 +6446,25 @@ share_mount_one(zfs_handle_t *zhp, int op, int flags, char *protocol,
                        return (1);
                }
 
-               if (zfs_mount(zhp, options, flags) != 0)
+               if (zfs_mount(zhp, options, flags) != 0) {
+                       /*
+                        * Check if a mount sneaked in after we checked
+                        */
+                       if (!explicit &&
+                           libzfs_errno(g_zfs) == EZFS_MOUNTFAILED) {
+                               usleep(10 * MILLISEC);
+                               libzfs_mnttab_cache(g_zfs, B_FALSE);
+
+                               if (zfs_is_mounted(zhp, NULL)) {
+                                       (void) fprintf(stderr, gettext(
+                                           "Ignoring previous 'already "
+                                           "mounted' error for '%s'\n"),
+                                           zfs_get_name(zhp));
+                                       return (0);
+                               }
+                       }
                        return (1);
+               }
                break;
        }