Whamcloud - gitweb
LU-16974 utils: make bandwidth options consistent
[fs/lustre-release.git] / lustre / target / tgt_mount.c
index 76d48ec..f35d45f 100644 (file)
@@ -1,44 +1,25 @@
-/*
- * GPL HEADER START
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 only,
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License version 2 for more details (a copy is included
- * in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU General Public License
- * version 2 along with this program; If not, see
- * http://www.gnu.org/licenses/gpl-2.0.html
- *
- * GPL HEADER END
- */
+// SPDX-License-Identifier: GPL-2.0
+
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
  * Copyright (c) 2013, 2017, Intel Corporation.
  */
+
 /*
  * This file is part of Lustre, http://www.lustre.org/
  *
- * lustre/obdclass/obd_mount_server.c
- *
  * Server mount routines
  *
  * Author: Nathan Rutman <nathan@clusterfs.com>
  */
+
 #define DEBUG_SUBSYSTEM S_CLASS
 #define D_MOUNT (D_SUPER | D_CONFIG /* | D_WARNING */)
 
 #include <linux/types.h>
-#include <linux/generic-radix-tree.h>
+#include <lustre_compat/linux/generic-radix-tree.h>
 #ifdef HAVE_LINUX_SELINUX_IS_ENABLED
 #include <linux/selinux.h>
 #endif
@@ -49,6 +30,7 @@
 #ifdef HAVE_FSMAP_H
 #include <linux/fsmap.h>
 #endif
+#include <linux/uaccess.h>
 
 #include <llog_swab.h>
 #include <lustre_disk.h>
@@ -231,8 +213,7 @@ static int server_start_mgs(struct super_block *sb)
        lmi = server_find_mount(LUSTRE_MGS_OBDNAME);
        if (lmi) {
                lsi = s2lsi(lmi->lmi_sb);
-               LCONSOLE_ERROR_MSG(0x15d,
-                                  "The MGS service was already started from server\n");
+               LCONSOLE_ERROR("The MGS service was already started from server\n");
                RETURN(-EALREADY);
        }
 
@@ -254,9 +235,8 @@ static int server_start_mgs(struct super_block *sb)
        if (rc < 0) {
                server_deregister_mount(LUSTRE_MGS_OBDNAME);
 report_err:
-               LCONSOLE_ERROR_MSG(0x15e,
-                                  "Failed to start MGS '%s' (%d). Is the 'mgs' module loaded?\n",
-                                  LUSTRE_MGS_OBDNAME, rc);
+               LCONSOLE_ERROR("Failed to start MGS '%s' (%d). Is the 'mgs' module loaded?\n",
+                              LUSTRE_MGS_OBDNAME, rc);
        }
        RETURN(rc);
 }
@@ -378,8 +358,7 @@ int tgt_name2lwp_name(const char *tgt_name, char *lwp_name, int len, u32 idx)
        GOTO(cleanup, rc = 0);
 
 cleanup:
-       if (fsname != NULL)
-               OBD_FREE(fsname, MTI_NAME_MAXLEN);
+       OBD_FREE(fsname, MTI_NAME_MAXLEN);
 
        return rc;
 }
@@ -416,7 +395,7 @@ int lustre_register_lwp_item(const char *lwpname, struct obd_export **exp,
                RETURN(-ENOMEM);
 
        lwp = class_name2obd(lwpname);
-       if (lwp && lwp->obd_set_up == 1) {
+       if (lwp && test_bit(OBDF_SET_UP, lwp->obd_flags)) {
                struct obd_uuid *uuid;
 
                OBD_ALLOC_PTR(uuid);
@@ -621,10 +600,8 @@ static int lustre_lwp_connect(struct obd_device *lwp, bool is_mdt)
        GOTO(out, rc);
 
 out:
-       if (data != NULL)
-               OBD_FREE_PTR(data);
-       if (uuid != NULL)
-               OBD_FREE_PTR(uuid);
+       OBD_FREE_PTR(data);
+       OBD_FREE_PTR(uuid);
 
        lu_env_fini(&env);
        lu_context_exit(&session_ctx);
@@ -644,9 +621,12 @@ static int lustre_lwp_setup(struct lustre_cfg *lcfg, struct lustre_sb_info *lsi,
        char *lwpname = NULL;
        char *lwpuuid = NULL;
        struct lnet_nid nid;
+       char *nidnet;
+       __u32 refnet;
        int rc;
 
        ENTRY;
+
        if (lcfg->lcfg_nid)
                lnet_nid4_to_nid(lcfg->lcfg_nid, &nid);
        else {
@@ -654,6 +634,12 @@ static int lustre_lwp_setup(struct lustre_cfg *lcfg, struct lustre_sb_info *lsi,
                if (rc)
                        RETURN(rc);
        }
+
+       nidnet = lsi->lsi_lmd->lmd_nidnet;
+       refnet = nidnet ? libcfs_str2net(nidnet) : LNET_NET_ANY;
+       if (refnet != LNET_NET_ANY && LNET_NID_NET(&nid) != refnet)
+               RETURN(-ENETUNREACH);
+
        rc = class_add_uuid(lustre_cfg_string(lcfg, 1), &nid);
        if (rc != 0) {
                CERROR("%s: Can't add uuid: rc =%d\n", lsi->lsi_svname, rc);
@@ -698,12 +684,10 @@ static int lustre_lwp_setup(struct lustre_cfg *lcfg, struct lustre_sb_info *lsi,
        list_add_tail(&obd->obd_lwp_list, &lsi->lsi_lwp_list);
        mutex_unlock(&lsi->lsi_lwp_mutex);
 out:
-       if (lwpname)
-               OBD_FREE(lwpname, MTI_NAME_MAXLEN);
-       if (lwpuuid)
-               OBD_FREE(lwpuuid, MTI_NAME_MAXLEN);
+       OBD_FREE(lwpname, MTI_NAME_MAXLEN);
+       OBD_FREE(lwpuuid, MTI_NAME_MAXLEN);
 
-       return rc;
+       RETURN(rc);
 }
 
 /* the caller is responsible for memory free */
@@ -773,18 +757,21 @@ static int lustre_lwp_add_conn(struct lustre_cfg *cfg,
        lustre_cfg_init(lcfg, LCFG_ADD_CONN, bufs);
 
        rc = class_add_conn(lwp, lcfg);
-       if (rc < 0)
+       if (rc == -ENETUNREACH) {
+               CDEBUG(D_CONFIG,
+                      "%s: ignore conn not on net %s: rc = %d\n",
+                      lwpname, lsi->lsi_lmd->lmd_nidnet, rc);
+               rc = 0;
+       } else if (rc < 0) {
                CERROR("%s: can't add conn: rc = %d\n", lwpname, rc);
+       }
 
-       if (lcfg)
-               OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount,
-                                             lcfg->lcfg_buflens));
+       OBD_FREE(lcfg, lustre_cfg_len(lcfg->lcfg_bufcount,
+                                     lcfg->lcfg_buflens));
 out_cfg:
-       if (bufs)
-               OBD_FREE_PTR(bufs);
+       OBD_FREE_PTR(bufs);
 out:
-       if (lwpname)
-               OBD_FREE(lwpname, MTI_NAME_MAXLEN);
+       OBD_FREE(lwpname, MTI_NAME_MAXLEN);
        RETURN(rc);
 }
 
@@ -811,9 +798,7 @@ static int client_lwp_config_process(const struct lu_env *env,
                                     struct llog_rec_hdr *rec, void *data)
 {
        struct config_llog_instance *cfg = data;
-       int cfg_len = rec->lrh_len;
-       char *cfg_buf = (char *) (rec + 1);
-       struct lustre_cfg *lcfg = NULL;
+       struct lustre_cfg *lcfg = REC_DATA(rec);
        struct lustre_sb_info *lsi;
        int rc = 0, swab = 0;
 
@@ -828,13 +813,12 @@ static int client_lwp_config_process(const struct lu_env *env,
                GOTO(out, rc = -EINVAL);
        lsi = s2lsi(cfg->cfg_sb);
 
-       lcfg = (struct lustre_cfg *)cfg_buf;
        if (lcfg->lcfg_version == __swab32(LUSTRE_CFG_VERSION)) {
                lustre_swab_lustre_cfg(lcfg);
                swab = 1;
        }
 
-       rc = lustre_cfg_sanity_check(cfg_buf, cfg_len);
+       rc = lustre_cfg_sanity_check(lcfg, REC_DATA_LEN(rec));
        if (rc < 0)
                GOTO(out, rc);
 
@@ -874,10 +858,13 @@ static int client_lwp_config_process(const struct lu_env *env,
        case LCFG_ADD_UUID: {
                if (cfg->cfg_flags == CFG_F_MARKER) {
                        rc = lustre_lwp_setup(lcfg, lsi, cfg->cfg_lwp_idx);
-                       /* XXX: process only the first nid as
+                       /* XXX: process only the first nid if on restricted net,
                         * we don't need another instance of lwp
                         */
-                       cfg->cfg_flags |= CFG_F_SKIP;
+                       if (rc == -ENETUNREACH)
+                               rc = 0;
+                       else
+                               cfg->cfg_flags |= CFG_F_SKIP;
                } else if (cfg->cfg_flags == (CFG_F_MARKER | CFG_F_SKIP)) {
                        struct lnet_nid nid;
 
@@ -1021,12 +1008,9 @@ static int lustre_disconnect_lwp(struct super_block *sb)
        GOTO(out, rc);
 
 out:
-       if (bufs)
-               OBD_FREE_PTR(bufs);
-       if (cfg)
-               OBD_FREE_PTR(cfg);
-       if (logname)
-               OBD_FREE(logname, MTI_NAME_MAXLEN);
+       OBD_FREE_PTR(bufs);
+       OBD_FREE_PTR(cfg);
+       OBD_FREE(logname, MTI_NAME_MAXLEN);
 
        return rc1 != 0 ? rc1 : rc;
 }
@@ -1096,6 +1080,7 @@ static int lustre_start_lwp(struct super_block *sb)
        cfg->cfg_callback = client_lwp_config_process;
        cfg->cfg_instance = ll_get_cfg_instance(sb);
        rc = lustre_process_log(sb, logname, cfg);
+
        /* need to remove config llog from mgc */
        lsi->lsi_lwp_started = 1;
 
@@ -1103,8 +1088,7 @@ static int lustre_start_lwp(struct super_block *sb)
 
 out:
        OBD_FREE(logname, MTI_NAME_MAXLEN);
-       if (cfg)
-               OBD_FREE_PTR(cfg);
+       OBD_FREE_PTR(cfg);
 
        return rc;
 }
@@ -1280,11 +1264,15 @@ static struct mgs_target_info *server_lsi2mti(struct lustre_sb_info *lsi)
        if (!mti)
                GOTO(free_list, mti = ERR_PTR(-ENOMEM));
 
-       if (strlcpy(mti->mti_svname, lsi->lsi_svname, sizeof(mti->mti_svname))
-           >= sizeof(mti->mti_svname))
-               GOTO(free_mti, rc = -E2BIG);
+       rc = strscpy(mti->mti_svname, lsi->lsi_svname, sizeof(mti->mti_svname));
+       if (rc < 0)
+               GOTO(free_mti, rc);
+
+       if (!large_nid && nid_count >= MTI_NIDS_MAX)
+               mti->mti_nid_count = MTI_NIDS_MAX;
+       else
+               mti->mti_nid_count = nid_count;
 
-       mti->mti_nid_count = nid_count;
        for (i = 0; i < mti->mti_nid_count; i++) {
                tmp = genradix_ptr(&plist, i);
 
@@ -1314,7 +1302,7 @@ static struct mgs_target_info *server_lsi2mti(struct lustre_sb_info *lsi)
        /* use NID strings instead */
        if (large_nid)
                mti->mti_flags |= LDD_F_LARGE_NID;
-       cplen = strlcpy(mti->mti_params, lsi->lsi_lmd->lmd_params,
+       cplen = strscpy(mti->mti_params, lsi->lsi_lmd->lmd_params,
                        sizeof(mti->mti_params));
        if (cplen >= sizeof(mti->mti_params))
                rc = -E2BIG;
@@ -1337,9 +1325,11 @@ static int server_register_target(struct lustre_sb_info *lsi)
        struct obd_device *mgc = lsi->lsi_mgc;
        struct mgs_target_info *mti = NULL;
        size_t mti_len = sizeof(*mti);
+       struct lnet_nid nid;
        bool must_succeed;
-       int rc;
        int tried = 0;
+       char *nidstr;
+       int rc;
 
        ENTRY;
        LASSERT(mgc);
@@ -1347,9 +1337,18 @@ static int server_register_target(struct lustre_sb_info *lsi)
        if (IS_ERR(mti))
                GOTO(out, rc = PTR_ERR(mti));
 
-       CDEBUG(D_MOUNT, "Registration %s, fs=%s, %s, index=%04x, flags=%#x\n",
-              mti->mti_svname, mti->mti_fsname, mti->mti_nidlist[0],
-              mti->mti_stripe_index, mti->mti_flags);
+       if (exp_connect_flags2(lsi->lsi_mgc->u.cli.cl_mgc_mgsexp) &
+           OBD_CONNECT2_LARGE_NID) {
+               nidstr = mti->mti_nidlist[0]; /* large_nid */
+       } else {
+               lnet_nid4_to_nid(mti->mti_nids[0], &nid);
+               nidstr = libcfs_nidstr(&nid);
+       }
+
+       CDEBUG(D_MOUNT,
+              "Registration %s, fs=%s, %s, index=%04x, flags=%#x\n",
+              mti->mti_svname, mti->mti_fsname, nidstr, mti->mti_stripe_index,
+              mti->mti_flags);
 
        /* we cannot ignore registration failure if MGS logs must be updated. */
        must_succeed = !!(lsi->lsi_flags &
@@ -1368,9 +1367,8 @@ again:
                                mti_len, mti, NULL);
        if (rc < 0) {
                if (mti->mti_flags & LDD_F_ERROR) {
-                       LCONSOLE_ERROR_MSG(0x160,
-                                          "%s: the MGS refuses to allow this server to start: rc = %d. Please see messages on the MGS.\n",
-                                          lsi->lsi_svname, rc);
+                       LCONSOLE_ERROR("%s: the MGS refuses to allow this server to start: rc = %d. Please see messages on the MGS.\n",
+                                      lsi->lsi_svname, rc);
                } else if (must_succeed) {
                        if ((rc == -ESHUTDOWN || rc == -EIO) && ++tried < 5) {
                                /* The connection with MGS is not established.
@@ -1381,9 +1379,8 @@ again:
                                        goto again;
                        }
 
-                       LCONSOLE_ERROR_MSG(0x15f,
-                                          "%s: cannot register this server with the MGS: rc = %d. Is the MGS running?\n",
-                                          lsi->lsi_svname, rc);
+                       LCONSOLE_ERROR("%s: cannot register this server with the MGS: rc = %d. Is the MGS running?\n",
+                                      lsi->lsi_svname, rc);
                } else {
                        CDEBUG(D_HA,
                               "%s: error registering with the MGS: rc = %d (not fatal)\n",
@@ -1463,8 +1460,11 @@ static int server_start_targets(struct super_block *sb)
                name_service = LUSTRE_OSS_NAME;
        }
 
-       /* make sure MDS/OSS is started */
-       mutex_lock(&server_start_lock);
+       /* make sure MDS/OSS is started, but allow mount to be killed */
+       rc = mutex_lock_interruptible(&server_start_lock);
+       if (rc)
+               RETURN(rc);
+
        obd = class_name2obd(obd_name_service);
        if (!obd) {
                rc = lustre_start_simple(obd_name_service, name_service,
@@ -1635,13 +1635,13 @@ static int lsi_prepare(struct lustre_sb_info *lsi)
            strlen(fstype) >= sizeof(lsi->lsi_fstype))
                RETURN(-ENAMETOOLONG);
 
-       strlcpy(lsi->lsi_svname, lsi->lsi_lmd->lmd_profile,
+       strscpy(lsi->lsi_svname, lsi->lsi_lmd->lmd_profile,
                sizeof(lsi->lsi_svname));
-       strlcpy(lsi->lsi_osd_type, osd_type, sizeof(lsi->lsi_osd_type));
+       strscpy(lsi->lsi_osd_type, osd_type, sizeof(lsi->lsi_osd_type));
        /* XXX: a temp. solution for components using ldiskfs
         *      to be removed in one of the subsequent patches
         */
-       strlcpy(lsi->lsi_fstype, fstype, sizeof(lsi->lsi_fstype));
+       strscpy(lsi->lsi_fstype, fstype, sizeof(lsi->lsi_fstype));
 
        /* Determine server type */
        rc = server_name2index(lsi->lsi_svname, &index, NULL);
@@ -1686,6 +1686,8 @@ static void server_put_super(struct super_block *sb)
        struct lustre_sb_info *lsi = s2lsi(sb);
        struct obd_device *obd;
        char *tmpname, *extraname = NULL;
+       struct lu_env env;
+       int rc;
        int tmpname_sz;
        int lsiflags = lsi->lsi_flags;
        bool stop_servers = lsi->lsi_server_started;
@@ -1711,6 +1713,15 @@ static void server_put_super(struct super_block *sb)
                              tmpname, rc);
        }
 
+       rc = lu_env_init(&env, LCT_DT_THREAD | LCT_MD_THREAD);
+       if (rc) {
+               CERROR("can't init env: rc=%d\n", rc);
+               GOTO(out, rc);
+       }
+       rc = lu_env_add(&env);
+       if (unlikely(rc))
+               GOTO(out_fini, rc);
+
        /* Stop the target */
        if (!test_bit(LMD_FLG_NOSVC, lsi->lsi_lmd->lmd_flags) &&
            (IS_MDT(lsi) || IS_OST(lsi))) {
@@ -1799,6 +1810,11 @@ static void server_put_super(struct super_block *sb)
                OBD_FREE(extraname, strlen(extraname) + 1);
        }
 
+       lu_env_remove(&env);
+out_fini:
+       lu_env_fini(&env);
+
+out:
        LCONSOLE(D_WARNING, "server umount %s complete\n", tmpname);
        OBD_FREE(tmpname, tmpname_sz);
        EXIT;
@@ -1969,7 +1985,7 @@ static int server_getattr(struct vfsmount *mnt, struct dentry *de,
        CDEBUG(D_SUPER, "%s: root_inode from %s ino=%lu, dev=%x\n",
               lsi->lsi_svname, root_inode == inode ? "lsi" : "vfsmnt",
               root_inode->i_ino, root_inode->i_rdev);
-       generic_fillattr(IDMAP_ARG root_inode, stat);
+       generic_fillattr(IDMAP_ARG RQMASK_ARG root_inode, stat);
        iput(root_inode);
 
        return 0;
@@ -2025,6 +2041,40 @@ static long server_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
        struct inode *root_inode;
        int err = -ENOTTY;
 
+       if (cmd == LL_IOC_FID2MDTIDX) {
+               union {
+                       struct lu_seq_range range;
+                       struct lu_fid fid;
+               } u;
+               struct lu_env *env;
+               int len;
+
+               if (copy_from_user(&u.fid, (struct lu_fid __user *)arg,
+                                  sizeof(u.fid)))
+                       RETURN(-EFAULT);
+
+               OBD_ALLOC_PTR(env);
+               if (env == NULL)
+                       return -ENOMEM;
+               err = lu_env_init(env, LCT_DT_THREAD);
+               if (err)
+                       GOTO(out, err = -ENOMEM);
+
+               /* XXX: check for size */
+               len = sizeof(struct lu_fid);
+               err = obd_get_info(env, lsi->lsi_osd_exp, sizeof(KEY_FID2IDX),
+                                  KEY_FID2IDX, &len, &u.fid);
+               if (err == 0) {
+                       err = -EINVAL;
+                       if (u.range.lsr_flags & LU_SEQ_RANGE_MDT)
+                               err = u.range.lsr_index;
+               }
+               lu_env_fini(env);
+out:
+               OBD_FREE_PTR(env);
+               return err;
+       }
+
        if (!is_cmd_supported(cmd))
                return err;
 
@@ -2196,9 +2246,8 @@ int server_fill_super(struct super_block *sb)
               lsi->lsi_svname, lsi->lsi_lmd->lmd_dev);
 
        if (class_name2obd(lsi->lsi_svname)) {
-               LCONSOLE_ERROR_MSG(0x161,
-                                  "The target named %s is already running. Double-mount may have compromised the disk journal.\n",
-                                  lsi->lsi_svname);
+               LCONSOLE_ERROR("The target named %s is already running. Double-mount may have compromised the disk journal.\n",
+                              lsi->lsi_svname);
                lustre_put_lsi(sb);
                RETURN(-EALREADY);
        }