Whamcloud - gitweb
LU-7846 nodemap: add fileset info to nodemap 83/18783/14
authorSebastien Buisson <sbuisson@ddn.com>
Fri, 5 Feb 2016 15:44:40 +0000 (16:44 +0100)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 2 Jun 2016 04:42:14 +0000 (04:42 +0000)
Give the ability to set a fileset information on a nodemap.
When set, a client pertaining to this nodemap will be allowed to
mount only the subdirectory represented by this fileset.

Fileset info of nodemap is stored permanently by using
'lctl set_param -P' commands. It means MDS and OSS will be able to
retrieve fileset info of nodemap after a restart (when they read
params llog).
MGS will not see fileset info after restart, but this does not prevent
the feature from working.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Signed-off-by: Kit Westneat <kit.westneat@gmail.com>
Change-Id: Ic16abaeb0b2fe583a9a4745258a82bbd23fc259e
Reviewed-on: http://review.whamcloud.com/18783
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Li Xi <lixi@ddn.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/lustre_cfg.h
lustre/include/lustre_nodemap.h
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_llog.c
lustre/ptlrpc/nodemap_handler.c
lustre/ptlrpc/nodemap_lproc.c
lustre/utils/lctl.c
lustre/utils/obd.c
lustre/utils/obdctl.h

index 71c65c3..f635786 100644 (file)
@@ -117,6 +117,7 @@ enum lcfg_command_type {
        LCFG_NODEMAP_DEL_SHKEY  = 0x00ce054, /**< delete shared key from cluster */
        LCFG_NODEMAP_TEST_NID   = 0x00ce055, /**< test for nodemap membership */
        LCFG_NODEMAP_TEST_ID    = 0x00ce056, /**< test uid/gid mapping */
        LCFG_NODEMAP_DEL_SHKEY  = 0x00ce054, /**< delete shared key from cluster */
        LCFG_NODEMAP_TEST_NID   = 0x00ce055, /**< test for nodemap membership */
        LCFG_NODEMAP_TEST_ID    = 0x00ce056, /**< test uid/gid mapping */
+       LCFG_NODEMAP_SET_FILESET   = 0x00ce057, /**< set fileset */
 };
 
 struct lustre_cfg_bufs {
 };
 
 struct lustre_cfg_bufs {
index b49774a..82931c0 100644 (file)
@@ -91,6 +91,8 @@ struct lu_nodemap {
        /* access by nodemap name */
        struct hlist_node        nm_hash;
        struct nodemap_pde      *nm_pde_data;
        /* access by nodemap name */
        struct hlist_node        nm_hash;
        struct nodemap_pde      *nm_pde_data;
+       /* fileset the nodes of this nodemap are restricted to */
+       char                     nm_fileset[PATH_MAX+1];
 
        /* used when loading/unloading nodemaps */
        struct list_head         nm_list;
 
        /* used when loading/unloading nodemaps */
        struct list_head         nm_list;
@@ -123,6 +125,8 @@ int nodemap_add_idmap(const char *name, enum nodemap_id_type id_type,
                      const __u32 map[2]);
 int nodemap_del_idmap(const char *name, enum nodemap_id_type id_type,
                      const __u32 map[2]);
                      const __u32 map[2]);
 int nodemap_del_idmap(const char *name, enum nodemap_id_type id_type,
                      const __u32 map[2]);
+int nodemap_set_fileset(const char *name, const char *fileset);
+char *nodemap_get_fileset(const struct lu_nodemap *nodemap);
 __u32 nodemap_map_id(struct lu_nodemap *nodemap,
                     enum nodemap_id_type id_type,
                     enum nodemap_tree_type tree_type, __u32 id);
 __u32 nodemap_map_id(struct lu_nodemap *nodemap,
                     enum nodemap_id_type id_type,
                     enum nodemap_tree_type tree_type, __u32 id);
index b60aef9..d59a49b 100644 (file)
@@ -752,6 +752,7 @@ static int mgs_iocontrol_nodemap(const struct lu_env *env,
        case LCFG_NODEMAP_DEL_UIDMAP:
        case LCFG_NODEMAP_ADD_GIDMAP:
        case LCFG_NODEMAP_DEL_GIDMAP:
        case LCFG_NODEMAP_DEL_UIDMAP:
        case LCFG_NODEMAP_ADD_GIDMAP:
        case LCFG_NODEMAP_DEL_GIDMAP:
+       case LCFG_NODEMAP_SET_FILESET:
                if (lcfg->lcfg_bufcount != 3)
                        GOTO(out_lcfg, rc = -EINVAL);
                nodemap_name = lustre_cfg_string(lcfg, 1);
                if (lcfg->lcfg_bufcount != 3)
                        GOTO(out_lcfg, rc = -EINVAL);
                nodemap_name = lustre_cfg_string(lcfg, 1);
index 6ba85ca..70a83dc 100644 (file)
@@ -4169,6 +4169,9 @@ int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
                        rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
                                               idmap);
                break;
                        rc = nodemap_del_idmap(nodemap_name, NODEMAP_GID,
                                               idmap);
                break;
+       case LCFG_NODEMAP_SET_FILESET:
+               rc = nodemap_set_fileset(nodemap_name, param);
+               break;
        default:
                rc = -EINVAL;
        }
        default:
                rc = -EINVAL;
        }
index 5f82521..10bbc49 100644 (file)
@@ -831,6 +831,72 @@ out:
 EXPORT_SYMBOL(nodemap_del_range);
 
 /**
 EXPORT_SYMBOL(nodemap_del_range);
 
 /**
+ * set fileset on nodemap
+ * \param      name            nodemap to set fileset on
+ * \param      fileset         string containing fileset
+ * \retval     0 on success
+ *
+ * set a fileset on the named nodemap
+ */
+static int nodemap_set_fileset_helper(struct nodemap_config *config,
+                                     struct lu_nodemap *nodemap,
+                                     const char *fileset)
+{
+       int rc = 0;
+
+       /* we allow fileset = "" which means clear fileset info */
+       if (fileset == NULL || (fileset[0] != 0 && fileset[0] != '/'))
+               rc = -EINVAL;
+       else if (strlcpy(nodemap->nm_fileset, fileset,
+                        sizeof(nodemap->nm_fileset)) >=
+                sizeof(nodemap->nm_fileset))
+               rc = -ENAMETOOLONG;
+
+       return rc;
+}
+
+int nodemap_set_fileset(const char *name, const char *fileset)
+{
+       struct lu_nodemap       *nodemap = NULL;
+       int                      rc = 0;
+
+       mutex_lock(&active_config_lock);
+       nodemap = nodemap_lookup(name);
+       if (IS_ERR(nodemap)) {
+               mutex_unlock(&active_config_lock);
+               GOTO(out, rc = PTR_ERR(nodemap));
+       }
+
+       if (is_default_nodemap(nodemap))
+               rc = -EINVAL;
+       else
+               rc = nodemap_set_fileset_helper(active_config, nodemap,
+                                               fileset);
+       mutex_unlock(&active_config_lock);
+
+       nodemap_putref(nodemap);
+out:
+       return rc;
+}
+EXPORT_SYMBOL(nodemap_set_fileset);
+
+/**
+ * get fileset defined on nodemap
+ * \param      nodemap         nodemap to get fileset from
+ * \retval     fileset name, or NULL if not defined or not activated
+ *
+ * get the fileset defined on the nodemap
+ */
+char *nodemap_get_fileset(const struct lu_nodemap *nodemap)
+{
+       if (!nodemap_active || is_default_nodemap(nodemap))
+               return NULL;
+       else
+               return (char *)nodemap->nm_fileset;
+}
+EXPORT_SYMBOL(nodemap_get_fileset);
+
+/**
  * Nodemap constructor
  *
  * Creates an lu_nodemap structure and assigns sane default
  * Nodemap constructor
  *
  * Creates an lu_nodemap structure and assigns sane default
@@ -923,6 +989,7 @@ struct lu_nodemap *nodemap_create(const char *name,
 
                nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
                nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
 
                nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
                nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
+               nodemap->nm_fileset[0] = 0;
        }
 
        return nodemap;
        }
 
        return nodemap;
index ce47326..fa6a6a7 100644 (file)
@@ -168,6 +168,61 @@ static int nodemap_ranges_open(struct inode *inode, struct file *file)
 }
 
 /**
 }
 
 /**
+ * Reads and prints the fileset for the given nodemap.
+ *
+ * \param      m               seq file in proc fs
+ * \param      data            unused
+ * \retval     0               success
+ */
+static int nodemap_fileset_seq_show(struct seq_file *m, void *data)
+{
+       struct lu_nodemap *nodemap;
+       int rc;
+
+       mutex_lock(&active_config_lock);
+       nodemap = nodemap_lookup(m->private);
+       mutex_unlock(&active_config_lock);
+       if (IS_ERR(nodemap)) {
+               rc = PTR_ERR(nodemap);
+               CERROR("cannot find nodemap '%s': rc = %d\n",
+                       (char *)m->private, rc);
+               return rc;
+       }
+
+       rc = seq_printf(m, "%s\n", nodemap->nm_fileset);
+       nodemap_putref(nodemap);
+       return rc;
+}
+
+/**
+ * Set a fileset on a nodemap.
+ *
+ * \param[in] file      proc file
+ * \param[in] buffer    string, "<fileset>"
+ * \param[in] count     \a buffer length
+ * \param[in] off       unused
+ * \retval              \a count on success
+ * \retval              negative number on error
+ */
+static ssize_t
+nodemap_fileset_seq_write(struct file *file,
+                                     const char __user *buffer,
+                                     size_t count, loff_t *off)
+{
+       struct seq_file *m = file->private_data;
+       int rc = 0;
+
+       if (count > 0)
+               rc = nodemap_set_fileset(m->private, buffer);
+
+       if (rc != 0)
+               return -EINVAL;
+
+       return count;
+}
+LPROC_SEQ_FOPS(nodemap_fileset);
+
+/**
  * Reads and prints the exports attached to the given nodemap.
  *
  * \param      m               seq file in proc fs, stores nodemap
  * Reads and prints the exports attached to the given nodemap.
  *
  * \param      m               seq file in proc fs, stores nodemap
@@ -1059,6 +1114,10 @@ static struct lprocfs_vars lprocfs_nodemap_vars[] = {
                .fops           = &nodemap_ranges_fops,
        },
        {
                .fops           = &nodemap_ranges_fops,
        },
        {
+               .name           = "fileset",
+               .fops           = &nodemap_fileset_fops,
+       },
+       {
                .name           = "exports",
                .fops           = &nodemap_exports_fops,
        },
                .name           = "exports",
                .fops           = &nodemap_exports_fops,
        },
index fe9d273..3d5eef2 100644 (file)
@@ -285,6 +285,9 @@ command_t cmdlist[] = {
         "add a UID or GID mapping to a nodemap"},
        {"nodemap_del_idmap", jt_nodemap_del_idmap, 0,
         "delete a UID or GID mapping from a nodemap"},
         "add a UID or GID mapping to a nodemap"},
        {"nodemap_del_idmap", jt_nodemap_del_idmap, 0,
         "delete a UID or GID mapping from a nodemap"},
+       {"nodemap_set_fileset", jt_nodemap_set_fileset, 0,
+        "set a fileset on a nodemap\n"
+        "usage: nodemap_set_fileset <fileset>"},
        {"nodemap_test_nid", jt_nodemap_test_nid, 0,
         "usage: nodemap_test_nid <nid>"},
        {"nodemap_test_id", jt_nodemap_test_id, 0,
        {"nodemap_test_nid", jt_nodemap_test_nid, 0,
         "usage: nodemap_test_nid <nid>"},
        {"nodemap_test_id", jt_nodemap_test_id, 0,
index 796140c..1ca0932 100644 (file)
@@ -3673,6 +3673,72 @@ int jt_nodemap_del_range(int argc, char **argv)
 }
 
 /**
 }
 
 /**
+ * set a fileset on a nodemap
+ *
+ * \param      argc            number of args
+ * \param      argv[]          variable string arguments
+ *
+ * --name                      nodemap name
+ * --fileset                   fileset name
+ *
+ * \retval                     0 on success
+ */
+int jt_nodemap_set_fileset(int argc, char **argv)
+{
+       char *nodemap_name = NULL;
+       char *fileset_name = NULL;
+       int   rc = 0;
+       int   c;
+
+       static struct option long_options[] = {
+               {
+                       .name           = "name",
+                       .has_arg        = required_argument,
+                       .flag           = 0,
+                       .val            = 'n',
+               },
+               {
+                       .name           = "fileset",
+                       .has_arg        = required_argument,
+                       .flag           = 0,
+                       .val            = 'f',
+               },
+               {
+                       NULL
+               }
+       };
+
+       while ((c = getopt_long(argc, argv, "n:f:",
+                               long_options, NULL)) != -1) {
+               switch (c) {
+               case 'n':
+                       nodemap_name = optarg;
+                       break;
+               case 'f':
+                       fileset_name = optarg;
+                       break;
+               }
+       }
+
+       if (nodemap_name == NULL || fileset_name == NULL) {
+               fprintf(stderr, "usage: nodemap_set_fileset --name <name> "
+                               "--fileset <fileset>\n");
+               return -1;
+       }
+
+       rc = nodemap_cmd(LCFG_NODEMAP_SET_FILESET, NULL, 0, argv[0],
+                        nodemap_name, fileset_name, NULL);
+       if (rc != 0) {
+               errno = -rc;
+               fprintf(stderr, "error: %s: cannot set fileset '%s' on nodemap "
+                               "'%s': rc = %d\n",
+                       jt_cmdname(argv[0]), fileset_name, nodemap_name, rc);
+       }
+
+       return rc;
+}
+
+/**
  * modify a nodemap's behavior
  *
  * \param      argc            number of args
  * modify a nodemap's behavior
  *
  * \param      argc            number of args
index 189e8ef..cd75d1f 100644 (file)
@@ -179,6 +179,7 @@ int jt_nodemap_del_range(int argc, char **argv);
 int jt_nodemap_add_idmap(int argc, char **argv);
 int jt_nodemap_del_idmap(int argc, char **argv);
 int jt_nodemap_test_id(int argc, char **argv);
 int jt_nodemap_add_idmap(int argc, char **argv);
 int jt_nodemap_del_idmap(int argc, char **argv);
 int jt_nodemap_test_id(int argc, char **argv);
+int jt_nodemap_set_fileset(int argc, char **argv);
 int jt_nodemap_info(int argc, char **argv);
 int jt_changelog_register(int argc, char **argv);
 int jt_changelog_deregister(int argc, char **argv);
 int jt_nodemap_info(int argc, char **argv);
 int jt_changelog_register(int argc, char **argv);
 int jt_changelog_deregister(int argc, char **argv);