Whamcloud - gitweb
LU-7759 utils: build mount.lustre with libmount 20/18820/5
authorYang Sheng <yang.sheng@intel.com>
Tue, 8 Mar 2016 17:21:14 +0000 (01:21 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 11 Apr 2016 02:51:41 +0000 (02:51 +0000)
Newer distro, like RHEL7, SLES12 will invoke statfs when
umount. It will block while some OST unavailable. So we
write a entry in utab file to avoid invoke statfs() before
issuing the unmount call.

Signed-off-by: Yang Sheng <yang.sheng@intel.com>
Change-Id: I3930ac3454a568908f0872f4a0d83ab264742f3c
Reviewed-on: http://review.whamcloud.com/18820
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Bob Glossman <bob.glossman@intel.com>
config/lustre-build.m4
lustre/utils/Makefile.am
lustre/utils/mount_lustre.c
lustre/utils/mount_utils.c
lustre/utils/mount_utils.h

index 950c1c4..3709185 100644 (file)
@@ -117,6 +117,25 @@ AC_SUBST(LIBCFS_SUBDIR)
 ]) # LB_LIBCFS_DIR
 
 #
 ]) # LB_LIBCFS_DIR
 
 #
+# LB_LIBMOUNT
+#
+# Check whether build with libmount for mount.lustre.
+# libmount is part of the util-linux since v2.18.
+# We need it to manipulate utab file.
+#
+AC_DEFUN([LB_LIBMOUNT], [
+AC_MSG_CHECKING([whether build with libmount])
+AC_CHECK_HEADER([libmount/libmount.h], [
+       AC_CHECK_LIB([mount], [mnt_update_set_fs], [
+               LDLIBMOUNT="-lmount"
+               AC_SUBST(LDLIBMOUNT)
+               AC_DEFINE(HAVE_LIBMOUNT, 1, [build with libmount])
+               AC_MSG_RESULT(yes)
+       ],[AC_MSG_RESULT(no)])
+], [AC_MSG_RESULT(no)])
+]) # LB_LIBMOUNT
+
+#
 # LB_PATH_SNMP
 #
 # check for in-tree snmp support
 # LB_PATH_SNMP
 #
 # check for in-tree snmp support
@@ -546,6 +565,7 @@ m4_ifdef([LC_NODEMAP_PROC_DEBUG], [LC_NODEMAP_PROC_DEBUG])
 LIBCFS_CONFIG_CDEBUG
 LC_QUOTA
 
 LIBCFS_CONFIG_CDEBUG
 LC_QUOTA
 
+LB_LIBMOUNT
 LB_PATH_SNMP
 LB_PATH_LUSTREIOKIT
 
 LB_PATH_SNMP
 LB_PATH_LUSTREIOKIT
 
index 4c68926..f2523be 100644 (file)
@@ -139,13 +139,13 @@ endif # LDISKFS_ENABLED
 mount_lustre_SOURCES = mount_lustre.c mount_utils.c mount_utils.h
 mount_lustre_CPPFLAGS := ${MNTMODCFLAGS}
 mount_lustre_LDFLAGS  := ${MNTMODLDFLAGS}
 mount_lustre_SOURCES = mount_lustre.c mount_utils.c mount_utils.h
 mount_lustre_CPPFLAGS := ${MNTMODCFLAGS}
 mount_lustre_LDFLAGS  := ${MNTMODLDFLAGS}
-mount_lustre_LDADD    := $(LIBPTLCTL) $(SELINUX)
+mount_lustre_LDADD    := $(LIBPTLCTL) $(SELINUX) $(LDLIBMOUNT)
 mount_lustre_DEPENDENCIES := $(LIBPTLCTL)
 
 mkfs_lustre_SOURCES = mkfs_lustre.c mount_utils.c mount_utils.h
 mkfs_lustre_CPPFLAGS := -UTUNEFS ${MNTMODCFLAGS}
 mkfs_lustre_LDFLAGS  := ${MNTMODLDFLAGS}
 mount_lustre_DEPENDENCIES := $(LIBPTLCTL)
 
 mkfs_lustre_SOURCES = mkfs_lustre.c mount_utils.c mount_utils.h
 mkfs_lustre_CPPFLAGS := -UTUNEFS ${MNTMODCFLAGS}
 mkfs_lustre_LDFLAGS  := ${MNTMODLDFLAGS}
-mkfs_lustre_LDADD    := $(LIBPTLCTL)
+mkfs_lustre_LDADD    := $(LIBPTLCTL) $(LDLIBMOUNT)
 mkfs_lustre_DEPENDENCIES := $(LIBPTLCTL)
 
 tunefs_lustre_SOURCES = mkfs_lustre.c mount_utils.c mount_utils.h
 mkfs_lustre_DEPENDENCIES := $(LIBPTLCTL)
 
 tunefs_lustre_SOURCES = mkfs_lustre.c mount_utils.c mount_utils.h
index 167aa61..0b9cafd 100644 (file)
 #endif
 #endif
 
 #endif
 #endif
 
+#ifdef HAVE_LIBMOUNT
+# define WITH_LIBMOUNT "(libmount)"
+#else
+# define WITH_LIBMOUNT ""
+#endif
+
 #define MAXOPT 4096
 #define MAX_RETRIES 99
 
 #define MAXOPT 4096
 #define MAX_RETRIES 99
 
@@ -554,8 +560,8 @@ static int parse_opts(int argc, char *const argv[], struct mount_opts *mop)
                        break;
                case 'V':
                        ++version;
                        break;
                case 'V':
                        ++version;
-                       fprintf(stdout, "%s %s\n", progname,
-                               LUSTRE_VERSION_STRING);
+                       fprintf(stdout, "%s %s %s\n", progname,
+                               LUSTRE_VERSION_STRING, WITH_LIBMOUNT);
                        return 0;
                default:
                        fprintf(stderr, "%s: unknown option '%c'\n",
                        return 0;
                default:
                        fprintf(stderr, "%s: unknown option '%c'\n",
@@ -806,9 +812,17 @@ int main(int argc, char *const argv[])
                                 rc = WEXITSTATUS(ret);
                 }
 
                                 rc = WEXITSTATUS(ret);
                 }
 
-       } else if (!mop.mo_nomtab) {
-               rc = update_mtab_entry(mop.mo_usource, mop.mo_target, "lustre",
-                                      mop.mo_orig_options, 0,0,0);
+       } else {
+               /* Deal with utab just for client. Note that we ignore
+                * the return value here since it is not worth to fail
+                * mount by prevent some rare cases */
+               if (strstr(mop.mo_usource, ":/") != NULL)
+                       update_utab_entry(&mop);
+               if (!mop.mo_nomtab) {
+                       rc = update_mtab_entry(mop.mo_usource, mop.mo_target,
+                                              "lustre", mop.mo_orig_options,
+                                              0, 0, 0);
+               }
        }
 
        free(options);
        }
 
        free(options);
index 2eb9daa..828874d 100644 (file)
@@ -239,6 +239,52 @@ static int mtab_is_proc(const char *mtab)
        return 1;
 }
 
        return 1;
 }
 
+#ifdef HAVE_LIBMOUNT
+
+# include <libmount/libmount.h>
+
+/*
+ * The libmount is part of util-linux since 2.18.
+ * We use it to update utab to avoid umount would
+ * blocked in some rare case.
+ */
+int update_utab_entry(struct mount_opts *mop)
+{
+       struct libmnt_fs *fs = mnt_new_fs();
+       struct libmnt_update *upd;
+       int rc;
+
+       mnt_fs_set_source(fs, mop->mo_source);
+       mnt_fs_set_target(fs, mop->mo_target);
+       mnt_fs_set_fstype(fs, "lustre");
+       mnt_fs_set_attributes(fs, "lustre");
+
+       upd = mnt_new_update();
+       if (!upd)
+               return -ENOMEM;
+
+       rc = mnt_update_set_fs(upd, mop->mo_nomtab ? MS_REMOUNT : 0, NULL, fs);
+       if (rc == 1) /* update is unnecessary */
+               rc = 0;
+       if (rc) {
+               fprintf(stderr,
+                       "error: failed to save utab entry: rc = %d\n", rc);
+       } else {
+               rc = mnt_update_table(upd, NULL);
+       }
+
+       mnt_free_update(upd);
+       mnt_free_fs(fs);
+
+       return rc;
+}
+#else
+int update_utab_entry(struct mount_opts *mop)
+{
+       return 0;
+}
+#endif /* HAVE_LIBMOUNT */
+
 int update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
                int flags, int freq, int pass)
 {
 int update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
                int flags, int freq, int pass)
 {
index 48afe0b..915b48f 100644 (file)
@@ -131,6 +131,7 @@ char *strscpy(char *dst, char *src, int buflen);
 int check_mtab_entry(char *spec1, char *spec2, char *mntpt, char *type);
 int update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
                      int flags, int freq, int pass);
 int check_mtab_entry(char *spec1, char *spec2, char *mntpt, char *type);
 int update_mtab_entry(char *spec, char *mtpt, char *type, char *opts,
                      int flags, int freq, int pass);
+int update_utab_entry(struct mount_opts *mop);
 int check_mountfsoptions(char *mountopts, char *wanted_mountopts);
 void trim_mountfsoptions(char *s);
 __u64 get_device_size(char* device);
 int check_mountfsoptions(char *mountopts, char *wanted_mountopts);
 void trim_mountfsoptions(char *s);
 __u64 get_device_size(char* device);