Whamcloud - gitweb
LU-1399 config: check lustre_cfg_new() return
[fs/lustre-release.git] / lustre / mgs / mgs_handler.c
index 1b5f2e0..3c006c5 100644 (file)
@@ -45,6 +45,7 @@
 
 #include <obd_class.h>
 #include <lprocfs_status.h>
+#include <lustre_ioctl.h>
 #include <lustre_param.h>
 
 #include "mgs_internal.h"
@@ -59,6 +60,7 @@ static int mgs_connect(struct tgt_session_info *tsi)
 
        ENTRY;
 
+       CFS_FAIL_TIMEOUT(OBD_FAIL_MGS_CONNECT_NET, cfs_fail_val);
        rc = tgt_connect(tsi);
        if (rc)
                RETURN(rc);
@@ -113,6 +115,8 @@ static int mgs_set_info(struct tgt_session_info *tsi)
        lustre_cfg_bufs_reset(&mgi->mgi_bufs, NULL);
        lustre_cfg_bufs_set_string(&mgi->mgi_bufs, 1, msp->mgs_param);
        lcfg = lustre_cfg_new(LCFG_PARAM, &mgi->mgi_bufs);
+       if (lcfg == NULL)
+               RETURN(-ENOMEM);
 
        rc = mgs_setparam(tsi->tsi_env, exp2mgs_dev(tsi->tsi_exp), lcfg,
                          mgi->mgi_fsname);
@@ -143,8 +147,7 @@ static int mgs_completion_ast_generic(struct ldlm_lock *lock, __u64 flags,
 {
        ENTRY;
 
-       if (!(flags & (LDLM_FL_BLOCK_WAIT | LDLM_FL_BLOCK_GRANTED |
-                      LDLM_FL_BLOCK_CONV))) {
+       if (!(flags & LDLM_FL_BLOCKED_MASK)) {
                struct fs_db *fsdb;
 
                /* l_ast_data is used as a marker to avoid cancel ldlm lock
@@ -538,11 +541,14 @@ static int mgs_llog_open(struct tgt_session_info *tsi)
        logname = req_capsule_client_get(tsi->tsi_pill, &RMF_NAME);
        if (logname) {
                char *ptr = strchr(logname, '-');
-               int   len = (int)(ptr - logname);
+               int   len = (ptr != NULL) ? (int)(ptr - logname) : 0;
 
                if (ptr == NULL || len >= sizeof(mgi->mgi_fsname)) {
-                       LCONSOLE_WARN("%s: non-config logname received: %s\n",
-                                     tgt_name(tsi->tsi_tgt), logname);
+                       if (strcmp(logname, PARAMS_FILENAME) != 0)
+                               LCONSOLE_WARN("%s: non-config logname "
+                                             "received: %s\n",
+                                             tgt_name(tsi->tsi_tgt),
+                                             logname);
                        /* not error, this can be llog test name */
                } else {
                        strncpy(mgi->mgi_fsname, logname, len);
@@ -573,7 +579,7 @@ static inline int mgs_init_export(struct obd_export *exp)
 
        /* init mgs_export_data for fsc */
        spin_lock_init(&data->med_lock);
-       CFS_INIT_LIST_HEAD(&data->med_clients);
+       INIT_LIST_HEAD(&data->med_clients);
 
        spin_lock(&exp->exp_lock);
        exp->exp_connecting = 1;
@@ -620,6 +626,139 @@ static int mgs_extract_fs_pool(char * arg, char *fsname, char *poolname)
         RETURN(0);
 }
 
+static int mgs_iocontrol_nodemap(const struct lu_env *env,
+                                struct mgs_device *mgs,
+                                struct obd_ioctl_data *data)
+{
+       struct lustre_cfg       *lcfg = NULL;
+       struct lu_nodemap       *nodemap;
+       lnet_nid_t              nid;
+       const char              *nodemap_name = NULL;
+       const char              *nidstr = NULL;
+       const char              *client_idstr = NULL;
+       const char              *idtype_str = NULL;
+       char                    *param = NULL;
+       char                    fs_idstr[16];
+       int                     rc = 0;
+       __u32                   client_id;
+       __u32                   fs_id;
+       __u32                   cmd;
+       int                     idtype;
+
+       ENTRY;
+
+       if (data->ioc_type != LUSTRE_CFG_TYPE) {
+               CERROR("%s: unknown cfg record type: %d\n",
+                      mgs->mgs_obd->obd_name, data->ioc_type);
+               GOTO(out, rc = -EINVAL);
+       }
+
+       if (data->ioc_plen1 > PAGE_CACHE_SIZE)
+               GOTO(out, rc = -E2BIG);
+
+       OBD_ALLOC(lcfg, data->ioc_plen1);
+       if (lcfg == NULL)
+               GOTO(out, rc = -ENOMEM);
+
+       if (copy_from_user(lcfg, data->ioc_pbuf1, data->ioc_plen1))
+               GOTO(out_lcfg, rc = -EFAULT);
+
+       cmd = lcfg->lcfg_command;
+
+       switch (cmd) {
+       case LCFG_NODEMAP_ACTIVATE:
+               if (lcfg->lcfg_bufcount != 2)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               param = lustre_cfg_string(lcfg, 1);
+               if (strcmp(param, "1") == 0)
+                               nodemap_activate(1);
+               else
+                               nodemap_activate(0);
+               break;
+       case LCFG_NODEMAP_ADD:
+       case LCFG_NODEMAP_DEL:
+               if (lcfg->lcfg_bufcount != 2)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nodemap_name = lustre_cfg_string(lcfg, 1);
+               rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param);
+               break;
+       case LCFG_NODEMAP_TEST_NID:
+               if (lcfg->lcfg_bufcount != 2)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nidstr = lustre_cfg_string(lcfg, 1);
+               nid = libcfs_str2nid(nidstr);
+               nodemap = nodemap_classify_nid(nid);
+               memset(data->ioc_pbuf1, 0, data->ioc_plen1);
+               if (copy_to_user(data->ioc_pbuf1, nodemap->nm_name,
+                                strlen(nodemap->nm_name)) != 0)
+                       GOTO(out_lcfg, rc = -EFAULT);
+               break;
+       case LCFG_NODEMAP_TEST_ID:
+               if (lcfg->lcfg_bufcount != 4)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nidstr = lustre_cfg_string(lcfg, 1);
+               idtype_str = lustre_cfg_string(lcfg, 2);
+               client_idstr = lustre_cfg_string(lcfg, 3);
+
+               nid = libcfs_str2nid(nidstr);
+               nodemap = nodemap_classify_nid(nid);
+               client_id = simple_strtoul(client_idstr, NULL, 10);
+
+               if (strcmp(idtype_str, "uid") == 0)
+                       idtype = NODEMAP_UID;
+               else
+                       idtype = NODEMAP_GID;
+
+               fs_id = nodemap_map_id(nodemap, idtype, NODEMAP_CLIENT_TO_FS,
+                                      client_id);
+
+               if (data->ioc_plen1 < sizeof(fs_idstr))
+                       GOTO(out_lcfg, rc = -EINVAL);
+
+               snprintf(fs_idstr, sizeof(fs_idstr), "%u", fs_id);
+               if (copy_to_user(data->ioc_pbuf1, fs_idstr,
+                                sizeof(fs_idstr)) != 0)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               break;
+       case LCFG_NODEMAP_ADD_RANGE:
+       case LCFG_NODEMAP_DEL_RANGE:
+       case LCFG_NODEMAP_ADD_UIDMAP:
+       case LCFG_NODEMAP_DEL_UIDMAP:
+       case LCFG_NODEMAP_ADD_GIDMAP:
+       case LCFG_NODEMAP_DEL_GIDMAP:
+               if (lcfg->lcfg_bufcount != 3)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nodemap_name = lustre_cfg_string(lcfg, 1);
+               param = lustre_cfg_string(lcfg, 2);
+               rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param);
+               break;
+       case LCFG_NODEMAP_ADMIN:
+       case LCFG_NODEMAP_TRUSTED:
+       case LCFG_NODEMAP_SQUASH_UID:
+       case LCFG_NODEMAP_SQUASH_GID:
+               if (lcfg->lcfg_bufcount != 4)
+                       GOTO(out_lcfg, rc = -EINVAL);
+               nodemap_name = lustre_cfg_string(lcfg, 1);
+               param = lustre_cfg_string(lcfg, 3);
+               rc = mgs_nodemap_cmd(env, mgs, cmd, nodemap_name, param);
+               break;
+       default:
+               rc = -ENOTTY;
+       }
+
+       if (rc != 0) {
+               CERROR("%s: OBD_IOC_NODEMAP command %X for %s: rc = %d\n",
+                      mgs->mgs_obd->obd_name, lcfg->lcfg_command,
+                      nodemap_name, rc);
+               GOTO(out_lcfg, rc);
+       }
+
+out_lcfg:
+       OBD_FREE(lcfg, data->ioc_plen1);
+out:
+       RETURN(rc);
+}
+
 static int mgs_iocontrol_pool(const struct lu_env *env,
                              struct mgs_device *mgs,
                               struct obd_ioctl_data *data)
@@ -792,8 +931,12 @@ out_free:
                rc = mgs_iocontrol_pool(&env, mgs, data);
                break;
 
-        case OBD_IOC_DUMP_LOG: {
-                struct llog_ctxt *ctxt;
+       case OBD_IOC_NODEMAP:
+               rc = mgs_iocontrol_nodemap(&env, mgs, data);
+               break;
+
+       case OBD_IOC_DUMP_LOG: {
+               struct llog_ctxt *ctxt;
 
                ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
                rc = class_config_dump_llog(&env, ctxt, data->ioc_inlbuf1,
@@ -803,6 +946,9 @@ out_free:
                break;
         }
 
+       case OBD_IOC_CATLOGLIST:
+               rc = mgs_list_logs(&env, mgs, data);
+               break;
        case OBD_IOC_LLOG_CANCEL:
        case OBD_IOC_LLOG_REMOVE:
         case OBD_IOC_LLOG_CHECK:
@@ -942,6 +1088,7 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs,
        struct obd_device               *obd;
        struct lustre_mount_info        *lmi;
        struct llog_ctxt                *ctxt;
+       struct fs_db                    *fsdb = NULL;
        int                              rc;
 
        ENTRY;
@@ -1013,6 +1160,14 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs,
                GOTO(err_llog, rc);
        }
 
+       /* Setup params fsdb and log, so that other servers can make a local
+        * copy successfully when they are mounted. See LU-4783 */
+       rc = mgs_params_fsdb_setup(env, mgs, fsdb);
+       if (rc)
+               /* params fsdb and log can be setup later */
+               CERROR("%s: %s fsdb and log setup failed: rc = %d\n",
+                      obd->obd_name, PARAMS_FILENAME, rc);
+
        ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
                           "mgs_ldlm_client", &obd->obd_ldlm_client);
 
@@ -1056,6 +1211,7 @@ static int mgs_init0(const struct lu_env *env, struct mgs_device *mgs,
        lu_site_purge(env, mgs2lu_dev(mgs)->ld_site, ~0);
        RETURN(0);
 err_lproc:
+       mgs_params_fsdb_cleanup(env, mgs);
        lproc_mgs_cleanup(mgs);
 err_llog:
        ctxt = llog_get_context(mgs->mgs_obd, LLOG_CONFIG_ORIG_CTXT);
@@ -1081,7 +1237,7 @@ err_ops:
        obd_disconnect(mgs->mgs_bottom_exp);
 err_lmi:
        if (lmi)
-               server_put_mount(lustre_cfg_string(lcfg, 0), lmi->lmi_mnt);
+               server_put_mount(lustre_cfg_string(lcfg, 0), true);
        RETURN(rc);
 }
 
@@ -1229,6 +1385,7 @@ static struct lu_device *mgs_device_fini(const struct lu_env *env,
        obd_zombie_barrier();
 
        tgt_fini(env, &mgs->mgs_lut);
+       mgs_params_fsdb_cleanup(env, mgs);
        mgs_cleanup_fsdb_list(mgs);
        lproc_mgs_cleanup(mgs);
 
@@ -1252,7 +1409,7 @@ static struct lu_device *mgs_device_fini(const struct lu_env *env,
        LASSERT(mgs->mgs_bottom_exp);
        obd_disconnect(mgs->mgs_bottom_exp);
 
-       server_put_mount(obd->obd_name, NULL);
+       server_put_mount(obd->obd_name, true);
 
        RETURN(NULL);
 }
@@ -1373,13 +1530,8 @@ static struct obd_ops mgs_obd_device_ops = {
 
 static int __init mgs_init(void)
 {
-       struct lprocfs_static_vars lvars;
-
-       lprocfs_mgs_init_vars(&lvars);
-       class_register_type(&mgs_obd_device_ops, NULL, lvars.module_vars,
-                           LUSTRE_MGS_NAME, &mgs_device_type);
-
-       return 0;
+       return class_register_type(&mgs_obd_device_ops, NULL, true, NULL,
+                                  LUSTRE_MGS_NAME, &mgs_device_type);
 }
 
 static void /*__exit*/ mgs_exit(void)