From f1de339d881958de8fc47065fb31a5c8e0c14b60 Mon Sep 17 00:00:00 2001 From: Yang Sheng Date: Wed, 9 Mar 2016 01:21:14 +0800 Subject: [PATCH] LU-7759 utils: build mount.lustre with libmount 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 Change-Id: I3930ac3454a568908f0872f4a0d83ab264742f3c Reviewed-on: http://review.whamcloud.com/18820 Tested-by: Jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Bob Glossman --- config/lustre-build.m4 | 20 ++++++++++++++++++++ lustre/utils/Makefile.am | 4 ++-- lustre/utils/mount_lustre.c | 24 ++++++++++++++++++----- lustre/utils/mount_utils.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ lustre/utils/mount_utils.h | 1 + 5 files changed, 88 insertions(+), 7 deletions(-) diff --git a/config/lustre-build.m4 b/config/lustre-build.m4 index 950c1c4..3709185 100644 --- a/config/lustre-build.m4 +++ b/config/lustre-build.m4 @@ -117,6 +117,25 @@ AC_SUBST(LIBCFS_SUBDIR) ]) # 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 @@ -546,6 +565,7 @@ m4_ifdef([LC_NODEMAP_PROC_DEBUG], [LC_NODEMAP_PROC_DEBUG]) LIBCFS_CONFIG_CDEBUG LC_QUOTA +LB_LIBMOUNT LB_PATH_SNMP LB_PATH_LUSTREIOKIT diff --git a/lustre/utils/Makefile.am b/lustre/utils/Makefile.am index 4c68926..f2523be 100644 --- a/lustre/utils/Makefile.am +++ b/lustre/utils/Makefile.am @@ -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_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} -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 diff --git a/lustre/utils/mount_lustre.c b/lustre/utils/mount_lustre.c index 167aa61..0b9cafd 100644 --- a/lustre/utils/mount_lustre.c +++ b/lustre/utils/mount_lustre.c @@ -72,6 +72,12 @@ #endif #endif +#ifdef HAVE_LIBMOUNT +# define WITH_LIBMOUNT "(libmount)" +#else +# define WITH_LIBMOUNT "" +#endif + #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; - 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", @@ -806,9 +812,17 @@ int main(int argc, char *const argv[]) 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); diff --git a/lustre/utils/mount_utils.c b/lustre/utils/mount_utils.c index 2eb9daa..828874d 100644 --- a/lustre/utils/mount_utils.c +++ b/lustre/utils/mount_utils.c @@ -239,6 +239,52 @@ static int mtab_is_proc(const char *mtab) return 1; } +#ifdef HAVE_LIBMOUNT + +# include + +/* + * 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) { diff --git a/lustre/utils/mount_utils.h b/lustre/utils/mount_utils.h index 48afe0b..915b48f 100644 --- a/lustre/utils/mount_utils.h +++ b/lustre/utils/mount_utils.h @@ -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 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); -- 1.8.3.1