Whamcloud - gitweb
LU-13004 ptlrpc: Allow BULK_BUF_KIOV to accept a kvec
[fs/lustre-release.git] / lustre / ptlrpc / sec_config.c
index fd248df..e7e08ed 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2015, Intel Corporation.
+ * Copyright (c) 2011, 2017, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -48,7 +44,7 @@
 #include <lustre_log.h>
 #include <lustre_disk.h>
 #include <lustre_dlm.h>
-#include <lustre_param.h>
+#include <uapi/linux/lustre/lustre_param.h>
 #include <lustre_sec.h>
 
 #include "ptlrpc_internal.h"
@@ -508,37 +504,6 @@ struct sptlrpc_conf {
 static struct mutex sptlrpc_conf_lock;
 static struct list_head sptlrpc_confs;
 
-static inline int is_hex(char c)
-{
-        return ((c >= '0' && c <= '9') ||
-                (c >= 'a' && c <= 'f'));
-}
-
-static void target2fsname(const char *tgt, char *fsname, int buflen)
-{
-        const char     *ptr;
-        int             len;
-
-        ptr = strrchr(tgt, '-');
-        if (ptr) {
-                if ((strncmp(ptr, "-MDT", 4) != 0 &&
-                     strncmp(ptr, "-OST", 4) != 0) ||
-                    !is_hex(ptr[4]) || !is_hex(ptr[5]) ||
-                    !is_hex(ptr[6]) || !is_hex(ptr[7]))
-                        ptr = NULL;
-        }
-
-        /* if we didn't find the pattern, treat the whole string as fsname */
-        if (ptr == NULL)
-                len = strlen(tgt);
-        else
-                len = ptr - tgt;
-
-        len = min(len, buflen - 1);
-        memcpy(fsname, tgt, len);
-        fsname[len] = '\0';
-}
-
 static void sptlrpc_conf_free_rsets(struct sptlrpc_conf *conf)
 {
        struct sptlrpc_conf_tgt *conf_tgt, *conf_tgt_next;
@@ -653,66 +618,86 @@ static int sptlrpc_conf_merge_rule(struct sptlrpc_conf *conf,
  * find one through the target name in the record inside conf_lock;
  * otherwise means caller already hold conf_lock.
  */
-static int __sptlrpc_process_config(struct lustre_cfg *lcfg,
-                                    struct sptlrpc_conf *conf)
+static int __sptlrpc_process_config(char *target, const char *fsname,
+                                   struct sptlrpc_rule *rule,
+                                   struct sptlrpc_conf *conf)
 {
-        char                   *target, *param;
-        char                    fsname[MTI_NAME_MAXLEN];
-        struct sptlrpc_rule     rule;
-        int                     rc;
-        ENTRY;
-
-        target = lustre_cfg_string(lcfg, 1);
-        if (target == NULL) {
-                CERROR("missing target name\n");
-                RETURN(-EINVAL);
-        }
-
-        param = lustre_cfg_string(lcfg, 2);
-        if (param == NULL) {
-                CERROR("missing parameter\n");
-                RETURN(-EINVAL);
-        }
-
-        CDEBUG(D_SEC, "processing rule: %s.%s\n", target, param);
+       int rc;
 
-        /* parse rule to make sure the format is correct */
-        if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
-                CERROR("Invalid sptlrpc parameter: %s\n", param);
-                RETURN(-EINVAL);
-        }
-        param += sizeof(PARAM_SRPC_FLVR) - 1;
-
-        rc = sptlrpc_parse_rule(param, &rule);
-        if (rc)
-                RETURN(-EINVAL);
-
-        if (conf == NULL) {
-                target2fsname(target, fsname, sizeof(fsname));
+       ENTRY;
+       if (!conf) {
+               if (!fsname)
+                       return -ENODEV;
 
                mutex_lock(&sptlrpc_conf_lock);
-                conf = sptlrpc_conf_get(fsname, 0);
-                if (conf == NULL) {
-                        CERROR("can't find conf\n");
-                        rc = -ENOMEM;
-                } else {
-                        rc = sptlrpc_conf_merge_rule(conf, target, &rule);
-                }
+               conf = sptlrpc_conf_get(fsname, 0);
+               if (!conf) {
+                       CERROR("can't find conf\n");
+                       rc = -ENOMEM;
+               } else {
+                       rc = sptlrpc_conf_merge_rule(conf, target, rule);
+               }
                mutex_unlock(&sptlrpc_conf_lock);
-        } else {
+       } else {
                LASSERT(mutex_is_locked(&sptlrpc_conf_lock));
-                rc = sptlrpc_conf_merge_rule(conf, target, &rule);
-        }
+               rc = sptlrpc_conf_merge_rule(conf, target, rule);
+       }
 
-        if (rc == 0)
-                conf->sc_modified++;
+       if (!rc)
+               conf->sc_modified++;
 
-        RETURN(rc);
+       RETURN(rc);
 }
 
 int sptlrpc_process_config(struct lustre_cfg *lcfg)
 {
-        return __sptlrpc_process_config(lcfg, NULL);
+       char fsname[MTI_NAME_MAXLEN];
+       struct sptlrpc_rule rule;
+       char *target, *param;
+       int rc;
+
+       print_lustre_cfg(lcfg);
+
+       target = lustre_cfg_string(lcfg, 1);
+       if (!target) {
+               CERROR("missing target name\n");
+               return -EINVAL;
+       }
+
+       param = lustre_cfg_string(lcfg, 2);
+       if (!param) {
+               CERROR("missing parameter\n");
+               return -EINVAL;
+       }
+
+       /* parse rule to make sure the format is correct */
+       if (strncmp(param, PARAM_SRPC_FLVR,
+                   sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
+               CERROR("Invalid sptlrpc parameter: %s\n", param);
+               return -EINVAL;
+       }
+       param += sizeof(PARAM_SRPC_FLVR) - 1;
+
+       CDEBUG(D_SEC, "processing rule: %s.%s\n", target, param);
+
+       /*
+        * Three types of targets exist for sptlrpc using conf_param
+        * 1.   '_mgs' which targets mgc srpc settings. Treat it as
+        *      as a special file system name.
+        * 2.   target is a device which can be fsname-MDTXXXX or
+        *      fsname-OSTXXXX. This can be verified by the function
+        *      server_name2fsname.
+        * 3.   If both above conditions are not meet then the target
+        *      is a actual filesystem.
+        */
+       if (server_name2fsname(target, fsname, NULL))
+               strlcpy(fsname, target, sizeof(target));
+
+       rc = sptlrpc_parse_rule(param, &rule);
+       if (rc)
+               return rc;
+
+       return __sptlrpc_process_config(target, fsname, &rule, NULL);
 }
 EXPORT_SYMBOL(sptlrpc_process_config);
 
@@ -859,7 +844,7 @@ void sptlrpc_conf_choose_flavor(enum lustre_sec_part from,
         char                     name[MTI_NAME_MAXLEN];
         int                      len, rc = 0;
 
-        target2fsname(target->uuid, name, sizeof(name));
+       obd_uuid2fsname(name, target->uuid, sizeof(name));
 
        mutex_lock(&sptlrpc_conf_lock);
 
@@ -926,11 +911,11 @@ void sptlrpc_conf_client_adapt(struct obd_device *obd)
 
        imp = obd->u.cli.cl_import;
        if (imp) {
-               spin_lock(&imp->imp_lock);
+               write_lock(&imp->imp_sec_lock);
                if (imp->imp_sec)
-                       imp->imp_sec_expire = cfs_time_current_sec() +
+                       imp->imp_sec_expire = ktime_get_real_seconds() +
                                SEC_ADAPT_DELAY;
-               spin_unlock(&imp->imp_lock);
+               write_unlock(&imp->imp_sec_lock);
        }
 
        up_read(&obd->u.cli.cl_sem);
@@ -938,281 +923,47 @@ void sptlrpc_conf_client_adapt(struct obd_device *obd)
 }
 EXPORT_SYMBOL(sptlrpc_conf_client_adapt);
 
-
-static void rule2string(struct sptlrpc_rule *r, char *buf, int buflen)
-{
-       char     dirbuf[8];
-       char     net[LNET_NIDSTR_SIZE] = "default";
-       char    *ptr = buf;
-
-       if (r->sr_netid != LNET_NIDNET(LNET_NID_ANY))
-               libcfs_net2str_r(r->sr_netid, net, sizeof(net));
-
-        if (r->sr_from == LUSTRE_SP_ANY && r->sr_to == LUSTRE_SP_ANY)
-                dirbuf[0] = '\0';
-        else
-                snprintf(dirbuf, sizeof(dirbuf), ".%s2%s",
-                         sptlrpc_part2name(r->sr_from),
-                         sptlrpc_part2name(r->sr_to));
-
-        ptr += snprintf(buf, buflen, "srpc.flavor.%s%s=", net, dirbuf);
-
-        sptlrpc_flavor2name(&r->sr_flvr, ptr, buflen - (ptr - buf));
-        buf[buflen - 1] = '\0';
-}
-
-static int sptlrpc_record_rule_set(struct llog_handle *llh,
-                                   char *target,
-                                   struct sptlrpc_rule_set *rset)
-{
-       struct llog_cfg_rec     *lcr;
-       struct lustre_cfg_bufs   bufs;
-       char                     param[48];
-       int                      i, rc;
-
-       for (i = 0; i < rset->srs_nrule; i++) {
-               rule2string(&rset->srs_rules[i], param, sizeof(param));
-
-               lustre_cfg_bufs_reset(&bufs, NULL);
-               lustre_cfg_bufs_set_string(&bufs, 1, target);
-               lustre_cfg_bufs_set_string(&bufs, 2, param);
-               lcr = lustre_cfg_rec_new(LCFG_SPTLRPC_CONF, &bufs);
-               if (lcr == NULL)
-                       return -ENOMEM;
-               rc = llog_write(NULL, llh, &lcr->lcr_hdr, LLOG_NEXT_IDX);
-               lustre_cfg_rec_free(lcr);
-               if (rc)
-                       return rc;
-       }
-       return 0;
-}
-
-static int sptlrpc_record_rules(struct llog_handle *llh,
-                                struct sptlrpc_conf *conf)
-{
-        struct sptlrpc_conf_tgt *conf_tgt;
-
-        sptlrpc_record_rule_set(llh, conf->sc_fsname, &conf->sc_rset);
-
-       list_for_each_entry(conf_tgt, &conf->sc_tgts, sct_list) {
-                sptlrpc_record_rule_set(llh, conf_tgt->sct_name,
-                                        &conf_tgt->sct_rset);
-        }
-        return 0;
-}
-
-#define LOG_SPTLRPC_TMP "sptlrpc.tmp"
-#define LOG_SPTLRPC     "sptlrpc"
-
-static
-int sptlrpc_target_local_copy_conf(struct obd_device *obd,
-                                   struct sptlrpc_conf *conf)
-{
-        struct llog_handle   *llh = NULL;
-        struct llog_ctxt     *ctxt;
-        struct lvfs_run_ctxt  saved;
-        struct dentry        *dentry;
-        int                   rc;
-        ENTRY;
-
-       ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
-       if (ctxt == NULL)
-               RETURN(-EINVAL);
-
-       push_ctxt(&saved, &obd->obd_lvfs_ctxt);
-
-       dentry = ll_lookup_one_len(MOUNT_CONFIGS_DIR, current->fs->pwd.dentry,
-                                   strlen(MOUNT_CONFIGS_DIR));
-        if (IS_ERR(dentry)) {
-                rc = PTR_ERR(dentry);
-                CERROR("cannot lookup %s directory: rc = %d\n",
-                       MOUNT_CONFIGS_DIR, rc);
-                GOTO(out_ctx, rc);
-        }
-
-        /* erase the old tmp log */
-       rc = llog_erase(NULL, ctxt, NULL, LOG_SPTLRPC_TMP);
-       if (rc < 0 && rc != -ENOENT) {
-               CERROR("%s: cannot erase temporary sptlrpc log: rc = %d\n",
-                      obd->obd_name, rc);
-               GOTO(out_dput, rc);
-       }
-
-       /* write temporary log */
-       rc = llog_open_create(NULL, ctxt, &llh, NULL, LOG_SPTLRPC_TMP);
-       if (rc)
-               GOTO(out_dput, rc);
-       rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
-        if (rc)
-                GOTO(out_close, rc);
-
-        rc = sptlrpc_record_rules(llh, conf);
-
-out_close:
-       llog_close(NULL, llh);
-       if (rc == 0)
-               rc = lustre_rename(dentry, obd->obd_lvfs_ctxt.pwdmnt,
-                                  LOG_SPTLRPC_TMP, LOG_SPTLRPC);
-out_dput:
-       dput(dentry);
-out_ctx:
-       pop_ctxt(&saved, &obd->obd_lvfs_ctxt);
-       llog_ctxt_put(ctxt);
-       CDEBUG(D_SEC, "target %s: write local sptlrpc conf: rc = %d\n",
-               obd->obd_name, rc);
-       RETURN(rc);
-}
-
-static int local_read_handler(const struct lu_env *env,
-                             struct llog_handle *llh,
-                             struct llog_rec_hdr *rec, void *data)
-{
-        struct sptlrpc_conf  *conf = (struct sptlrpc_conf *) data;
-        struct lustre_cfg    *lcfg = (struct lustre_cfg *)(rec + 1);
-        int                   cfg_len, rc;
-        ENTRY;
-
-        if (rec->lrh_type != OBD_CFG_REC) {
-                CERROR("unhandled lrh_type: %#x\n", rec->lrh_type);
-                RETURN(-EINVAL);
-        }
-
-        cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) -
-                  sizeof(struct llog_rec_tail);
-
-        rc = lustre_cfg_sanity_check(lcfg, cfg_len);
-        if (rc) {
-                CERROR("Insane cfg\n");
-                RETURN(rc);
-        }
-
-        if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) {
-                CERROR("invalid command (%x)\n", lcfg->lcfg_command);
-                RETURN(-EINVAL);
-        }
-
-        RETURN(__sptlrpc_process_config(lcfg, conf));
-}
-
-static
-int sptlrpc_target_local_read_conf(struct obd_device *obd,
-                                   struct sptlrpc_conf *conf)
-{
-        struct llog_handle    *llh = NULL;
-        struct llog_ctxt      *ctxt;
-        struct lvfs_run_ctxt   saved;
-        int                    rc;
-        ENTRY;
-
-        LASSERT(conf->sc_updated == 0 && conf->sc_local == 0);
-
-        ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT);
-        if (ctxt == NULL) {
-                CERROR("missing llog context\n");
-                RETURN(-EINVAL);
-        }
-
-       push_ctxt(&saved, &obd->obd_lvfs_ctxt);
-
-       rc = llog_open(NULL, ctxt, &llh, NULL, LOG_SPTLRPC, LLOG_OPEN_EXISTS);
-       if (rc < 0) {
-               if (rc == -ENOENT)
-                       rc = 0;
-               GOTO(out_pop, rc);
-       }
-
-       rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL);
-        if (rc)
-                GOTO(out_close, rc);
-
-        if (llog_get_size(llh) <= 1) {
-                CDEBUG(D_SEC, "no local sptlrpc copy found\n");
-                GOTO(out_close, rc = 0);
-        }
-
-       rc = llog_process(NULL, llh, local_read_handler, (void *)conf, NULL);
-
-        if (rc == 0) {
-                conf->sc_local = 1;
-        } else {
-                sptlrpc_conf_free_rsets(conf);
-        }
-
-out_close:
-       llog_close(NULL, llh);
-out_pop:
-       pop_ctxt(&saved, &obd->obd_lvfs_ctxt);
-       llog_ctxt_put(ctxt);
-       CDEBUG(D_SEC, "target %s: read local sptlrpc conf: rc = %d\n",
-               obd->obd_name, rc);
-       RETURN(rc);
-}
-
-
 /**
  * called by target devices, extract sptlrpc rules which applies to
  * this target, to be used for future rpc flavor checking.
  */
 int sptlrpc_conf_target_get_rules(struct obd_device *obd,
-                                  struct sptlrpc_rule_set *rset,
-                                  int initial)
-{
-        struct sptlrpc_conf      *conf;
-        struct sptlrpc_conf_tgt  *conf_tgt;
-        enum lustre_sec_part      sp_dst;
-        char                      fsname[MTI_NAME_MAXLEN];
-        int                       rc = 0;
-        ENTRY;
-
-        if (strcmp(obd->obd_type->typ_name, LUSTRE_MDT_NAME) == 0) {
-                sp_dst = LUSTRE_SP_MDT;
-        } else if (strcmp(obd->obd_type->typ_name, LUSTRE_OST_NAME) == 0) {
-                sp_dst = LUSTRE_SP_OST;
-        } else {
-                CERROR("unexpected obd type %s\n", obd->obd_type->typ_name);
-                RETURN(-EINVAL);
-        }
-        CDEBUG(D_SEC, "get rules for target %s\n", obd->obd_uuid.uuid);
+                                 struct sptlrpc_rule_set *rset)
+{
+       struct sptlrpc_conf *conf;
+       struct sptlrpc_conf_tgt *conf_tgt;
+       enum lustre_sec_part sp_dst;
+       char fsname[MTI_NAME_MAXLEN];
+       int rc = 0;
+       ENTRY;
+
+       if (strcmp(obd->obd_type->typ_name, LUSTRE_MDT_NAME) == 0) {
+               sp_dst = LUSTRE_SP_MDT;
+       } else if (strcmp(obd->obd_type->typ_name, LUSTRE_OST_NAME) == 0) {
+               sp_dst = LUSTRE_SP_OST;
+       } else {
+               CERROR("unexpected obd type %s\n", obd->obd_type->typ_name);
+               RETURN(-EINVAL);
+       }
 
-        target2fsname(obd->obd_uuid.uuid, fsname, sizeof(fsname));
+       obd_uuid2fsname(fsname, obd->obd_uuid.uuid, sizeof(fsname));
 
        mutex_lock(&sptlrpc_conf_lock);
-
-        conf = sptlrpc_conf_get(fsname, 0);
-        if (conf == NULL) {
-                CERROR("missing sptlrpc config log\n");
-                GOTO(out, rc);
-        }
-
-        if (conf->sc_updated  == 0) {
-                /*
-                 * always read from local copy. here another option is
-                 * if we already have a local copy (read from another
-                 * target device hosted on the same node) we simply use that.
-                 */
-                if (conf->sc_local)
-                        sptlrpc_conf_free_rsets(conf);
-
-                sptlrpc_target_local_read_conf(obd, conf);
-        } else {
-                LASSERT(conf->sc_local == 0);
-
-                /* write a local copy */
-                if (initial || conf->sc_modified)
-                        sptlrpc_target_local_copy_conf(obd, conf);
-                else
-                        CDEBUG(D_SEC, "unchanged, skip updating local copy\n");
-        }
-
-        /* extract rule set for this target */
-        conf_tgt = sptlrpc_conf_get_tgt(conf, obd->obd_name, 0);
-
-        rc = sptlrpc_rule_set_extract(&conf->sc_rset,
-                                      conf_tgt ? &conf_tgt->sct_rset: NULL,
-                                      LUSTRE_SP_ANY, sp_dst, rset);
-out:
+       conf = sptlrpc_conf_get(fsname, 0);
+       if (conf == NULL) {
+               CERROR("missing sptlrpc config log\n");
+               rc = -EFAULT;
+       } else {
+               /* extract rule set for this target */
+               conf_tgt = sptlrpc_conf_get_tgt(conf, obd->obd_name, 0);
+
+               rc = sptlrpc_rule_set_extract(&conf->sc_rset,
+                                     conf_tgt ? &conf_tgt->sct_rset : NULL,
+                                     LUSTRE_SP_ANY, sp_dst, rset);
+       }
        mutex_unlock(&sptlrpc_conf_lock);
-        RETURN(rc);
+
+       RETURN(rc);
 }
 
 int  sptlrpc_conf_init(void)