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>
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 {
/* 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;
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);
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);
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;
}
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->nm_squash_uid = default_nodemap->nm_squash_uid;
nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
+ nodemap->nm_fileset[0] = 0;
}
return nodemap;
}
/**
+ * 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
.fops = &nodemap_ranges_fops,
},
{
+ .name = "fileset",
+ .fops = &nodemap_fileset_fops,
+ },
+ {
.name = "exports",
.fops = &nodemap_exports_fops,
},
"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,
}
/**
+ * 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
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);