# two macros for cmd3
m4_ifdef([LC_CONFIG_SPLIT], [LC_CONFIG_SPLIT])
+m4_ifdef([LC_NODEMAP_PROC_DEBUG], [LC_NODEMAP_PROC_DEBUG])
LN_CONFIG_CDEBUG
LC_QUOTA
subdir-m += ptlrpc
subdir-m += obdecho
subdir-m += mgc
+subdir-m += nodemap
-@SERVER_TRUE@subdir-m += ost mgs mdt mdd ofd quota osp lod lfsck
+@SERVER_TRUE@subdir-m += ost mgs mdt mdd ofd quota osp lod lfsck nodemap
@CLIENT_TRUE@subdir-m += lov osc mdc lmv llite fld
@LDISKFS_ENABLED_TRUE@subdir-m += osd-ldiskfs
@ZFS_ENABLED_TRUE@subdir-m += osd-zfs
mgc fid fld doc utils tests scripts autoconf contrib conf
SERVER_SUBDIRS = ost mgs mdt mdd ofd osd-zfs osd-ldiskfs \
- quota osp lod target lfsck
+ quota osp lod target lfsck nodemap
CLIENT_SUBDIRS = mdc lmv llite lclient lov osc
])
#
+# LC_CONFIG_NODEMAP_PROC_DEBUG
+#
+# enable nodemap proc file debugging
+#
+AC_DEFUN([LC_NODEMAP_PROC_DEBUG],
+[AC_MSG_CHECKING([whether to enable nodemap proc debug])
+AC_ARG_ENABLE([nodemap_proc_debug],
+ AC_HELP_STRING([--enable-nodemap-proc-debug],
+ [enable nodemap proc debug]),
+ [],[enable_nodemap_proc_debug='no'])
+AC_MSG_RESULT([$enable_nodemap_proc_debug])
+if test x$enable_nodemap_proc_debug != xno; then
+ AC_DEFINE(NODEMAP_PROC_DEBUG, 1, [enable nodemap proc debug support])
+fi
+])
+
+#
# LC_LLITE_LLOOP_MODULE
# lloop_llite.ko does not currently work with page sizes
# of 64k or larger.
lustre/lfsck/autoMakefile
lustre/mdt/Makefile
lustre/mdt/autoMakefile
+lustre/nodemap/Makefile
+lustre/nodemap/autoMakefile
lustre/mdd/Makefile
lustre/mdd/autoMakefile
lustre/fld/Makefile
lustre_mdc.h \
lustre_mds.h \
lustre_net.h \
+ lustre_nodemap.h \
lustre_param.h \
lustre_quota.h \
lustre_req_layout.h \
char *obd_uuid, void *args);
extern int llapi_search_rootpath(char *pathname, const char *fsname);
+extern int llapi_nodemap_exists(const char *name);
struct mntent;
#define HAVE_LLAPI_IS_LUSTRE_MNT
* cleanup cleanup */
LCFG_SET_PARAM = 0x00ce032, /**< use set_param syntax to set
*a proc parameters */
+ LCFG_NODEMAP_ADD = 0x00ce040, /**< create a cluster */
+ LCFG_NODEMAP_DEL = 0x00ce041, /**< destroy a cluster */
+ LCFG_NODEMAP_ADD_RANGE = 0x00ce042, /**< add a nid range */
+ LCFG_NODEMAP_DEL_RANGE = 0x00ce043, /**< delete an nid range */
+ LCFG_NODEMAP_ADD_UIDMAP = 0x00ce044, /**< add a uidmap */
+ LCFG_NODEMAP_DEL_UIDMAP = 0x00ce045, /**< delete a uidmap */
+ LCFG_NODEMAP_ADD_GIDMAP = 0x00ce046, /**< add a gidmap */
+ LCFG_NODEMAP_DEL_GIDMAP = 0x00ce047, /**< delete a gidmap */
+ LCFG_NODEMAP_ACTIVATE = 0x00ce048, /**< activate cluster id mapping */
+ LCFG_NODEMAP_ADMIN = 0x00ce049, /**< allow cluster to use id 0 */
+ LCFG_NODEMAP_TRUSTED = 0x00ce050, /**< trust a clusters ids */
+ LCFG_NODEMAP_SQUASH_UID = 0x00ce051, /**< default map uid */
+ LCFG_NODEMAP_SQUASH_GID = 0x00ce052, /**< default map gid */
+ LCFG_NODEMAP_ADD_SHKEY = 0x00ce053, /**< add shared key to cluster */
+ LCFG_NODEMAP_DEL_SHKEY = 0x00ce054, /**< delete shared key from cluster */
};
struct lustre_cfg_bufs {
struct ec_export_data eu_ec_data;
struct mgs_export_data eu_mgs_data;
} u;
+
+ struct nodemap *exp_nodemap;
};
#define exp_target_data u.eu_target_data
#define OBD_IOC_LLOG_CHECK _IOWR('f', 195, OBD_IOC_DATA_TYPE)
/* OBD_IOC_LLOG_CATINFO is deprecated */
#define OBD_IOC_LLOG_CATINFO _IOWR('f', 196, OBD_IOC_DATA_TYPE)
+#define OBD_IOC_NODEMAP _IOWR('f', 197, OBD_IOC_DATA_TYPE)
#define ECHO_IOC_GET_STRIPE _IOWR('f', 200, OBD_IOC_DATA_TYPE)
#define ECHO_IOC_SET_STRIPE _IOWR('f', 201, OBD_IOC_DATA_TYPE)
--- /dev/null
+/*
+ * 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.sun.com/software/products/lustre/docs/GPLv2.pdf
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (C) 2013, Trustees of Indiana University
+ * Author: Joshua Walgenbach <jjw@iu.edu>
+ */
+
+#ifndef _LUSTRE_NODEMAP_H
+#define _LUSTRE_NODEMAP_H
+
+#define LUSTRE_NODEMAP_NAME "nodemap"
+#define LUSTRE_NODEMAP_NAME_LENGTH 16
+
+#define LUSTRE_NODEMAP_DEFAULT_ID 0
+
+/** The nodemap id 0 will be the default nodemap. It will have a configuration
+ * set by the MGS, but no ranges will be allowed as all NIDs that do not map
+ * will be added to the default nodemap
+ */
+
+struct lu_nodemap {
+ /* human readable ID */
+ char nm_name[LUSTRE_NODEMAP_NAME_LENGTH + 1];
+ /* flags to govern nodemap behavior */
+ bool nmf_trust_client_ids:1,
+ nmf_allow_root_access:1,
+ nmf_block_lookups:1,
+ nmf_hmac_required:1,
+ nmf_encryption_required:1;
+ /* unique ID set by MGS */
+ int nm_id;
+ /* nodemap ref counter */
+ atomic_t nm_refcount;
+ /* UID to squash unmapped UIDs */
+ uid_t nm_squash_uid;
+ /* GID to squash unmapped GIDs */
+ gid_t nm_squash_gid;
+ /* NID range list */
+ struct list_head nm_ranges;
+ /* UID map keyed by local UID */
+ struct rb_root nm_local_to_remote_uidmap;
+ /* UID map keyed by remote UID */
+ struct rb_root nm_remote_to_local_uidmap;
+ /* GID map keyed by local UID */
+ struct rb_root nm_local_to_remote_gidmap;
+ /* GID map keyed by remote UID */
+ struct rb_root nm_remote_to_local_gidmap;
+ /* proc directory entry */
+ struct proc_dir_entry *nm_proc_entry;
+ /* attached client members of this nodemap */
+ struct list_head nm_exports;
+ /* access by nodemap name */
+ cfs_hlist_node_t nm_hash;
+};
+
+int nodemap_add(const char *nodemap_name);
+int nodemap_del(const char *nodemap_name);
+
+#endif
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;
+ const char *nodemap_name;
+ char *param = NULL;
+ __u32 cmd;
+ int rc = 0;
+ 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);
+
+ nodemap_name = lustre_cfg_string(lcfg, 1);
+ cmd = lcfg->lcfg_command;
+
+ switch (cmd) {
+ case LCFG_NODEMAP_ADD:
+ case LCFG_NODEMAP_DEL:
+ if (lcfg->lcfg_bufcount != 2)
+ GOTO(out_lcfg, rc = -EINVAL);
+ 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)
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,
#include <libcfs/libcfs.h>
#include <lustre_log.h>
#include <lustre_export.h>
+#include <lustre_nodemap.h>
#include <dt_object.h>
#define MGSSELF_NAME "_mgs"
int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
enum lcfg_command_type cmd, char *poolname, char *fsname,
char *ostname);
+int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
+ enum lcfg_command_type cmd, const char *nodemap_name,
+ const char *param);
/* mgs_handler.c */
int mgs_get_lock(struct obd_device *obd, struct ldlm_res_id *res,
return rc;
}
+int mgs_nodemap_cmd(const struct lu_env *env, struct mgs_device *mgs,
+ enum lcfg_command_type cmd, const char *nodemap_name,
+ const char *param)
+{
+ int rc = 0;
+ ENTRY;
+
+ switch (cmd) {
+ case LCFG_NODEMAP_ADD:
+ rc = nodemap_add(nodemap_name);
+ break;
+ case LCFG_NODEMAP_DEL:
+ rc = nodemap_del(nodemap_name);
+ break;
+ default:
+ rc = -EINVAL;
+ }
+
+ RETURN(rc);
+}
+
int mgs_pool_cmd(const struct lu_env *env, struct mgs_device *mgs,
enum lcfg_command_type cmd, char *fsname,
char *poolname, char *ostname)
--- /dev/null
+MODULES := nodemap
+nodemap-objs := nodemap_handler.o nodemap_lproc.o
+
+@INCLUDE_RULES@
--- /dev/null
+#
+# 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
+
+if MODULES
+modulefs_DATA = nodemap$(KMODEXT)
+endif
+
+MOSTLYCLEANFILES := @MOSTLYCLEANFILES@
+EXTRA_DIST := $(nodemap-objs:%.o=%.c) nodemap_internal.h
--- /dev/null
+/*
+ * 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
+ */
+/*
+ * Copyright (C) 2013, Trustees of Indiana University
+ * Author: Joshua Walgenbach <jjw@iu.edu>
+ */
+#include <linux/module.h>
+#include <lustre_net.h>
+#include "nodemap_internal.h"
+
+#define HASH_NODEMAP_BKT_BITS 3
+#define HASH_NODEMAP_CUR_BITS 3
+#define HASH_NODEMAP_MAX_BITS 7
+
+#define DEFAULT_NODEMAP "default"
+
+/* nodemap proc root proc directory under fs/lustre */
+struct proc_dir_entry *proc_lustre_nodemap_root;
+
+/* Highest numerical lu_nodemap.nm_id defined */
+static atomic_t nodemap_highest_id;
+
+/* Simple flag to determine if nodemaps are active */
+bool nodemap_idmap_active;
+
+/**
+ * pointer to default nodemap kept to keep from
+ * lookup it up in the hash since it is needed
+ * more often
+ */
+static struct lu_nodemap *default_nodemap;
+
+/**
+ * Hash keyed on nodemap name containing all
+ * nodemaps
+ */
+static cfs_hash_t *nodemap_hash;
+
+/**
+ * Nodemap destructor
+ *
+ * \param nodemap nodemap to destroy
+ */
+static void nodemap_destroy(struct lu_nodemap *nodemap)
+{
+ lprocfs_remove(&(nodemap->nm_proc_entry));
+ OBD_FREE_PTR(nodemap);
+}
+
+/**
+ * Functions used for the cfs_hash
+ */
+static void nodemap_getref(struct lu_nodemap *nodemap)
+{
+ CDEBUG(D_INFO, "nodemap %p\n", nodemap);
+ atomic_inc(&nodemap->nm_refcount);
+}
+
+void nodemap_putref(struct lu_nodemap *nodemap)
+{
+ LASSERT(nodemap != NULL);
+ LASSERT(cfs_atomic_read(&nodemap->nm_refcount) > 0);
+
+ if (atomic_dec_and_test(&nodemap->nm_refcount))
+ nodemap_destroy(nodemap);
+}
+
+static __u32 nodemap_hashfn(cfs_hash_t *hash_body,
+ const void *key, unsigned mask)
+{
+ const struct lu_nodemap *nodemap = key;
+
+ return cfs_hash_djb2_hash(nodemap->nm_name, strlen(nodemap->nm_name),
+ mask);
+}
+
+static void *nodemap_hs_key(cfs_hlist_node_t *hnode)
+{
+ struct lu_nodemap *nodemap;
+
+ nodemap = cfs_hlist_entry(hnode, struct lu_nodemap, nm_hash);
+ return nodemap->nm_name;
+}
+
+static int nodemap_hs_keycmp(const void *key,
+ cfs_hlist_node_t *compared_hnode)
+{
+ struct lu_nodemap *nodemap;
+
+ nodemap = nodemap_hs_key(compared_hnode);
+ return !strcmp(key, nodemap->nm_name);
+}
+
+static void *nodemap_hs_hashobject(cfs_hlist_node_t *hnode)
+{
+ return cfs_hlist_entry(hnode, struct lu_nodemap, nm_hash);
+}
+
+static void nodemap_hs_get(cfs_hash_t *hs, cfs_hlist_node_t *hnode)
+{
+ struct lu_nodemap *nodemap;
+
+ nodemap = cfs_hlist_entry(hnode, struct lu_nodemap, nm_hash);
+ nodemap_getref(nodemap);
+}
+
+static void nodemap_hs_put_locked(cfs_hash_t *hs,
+ cfs_hlist_node_t *hnode)
+{
+ struct lu_nodemap *nodemap;
+
+ nodemap = cfs_hlist_entry(hnode, struct lu_nodemap, nm_hash);
+ nodemap_putref(nodemap);
+}
+
+static cfs_hash_ops_t nodemap_hash_operations = {
+ .hs_hash = nodemap_hashfn,
+ .hs_key = nodemap_hs_key,
+ .hs_keycmp = nodemap_hs_keycmp,
+ .hs_object = nodemap_hs_hashobject,
+ .hs_get = nodemap_hs_get,
+ .hs_put_locked = nodemap_hs_put_locked,
+};
+
+/* end of cfs_hash functions */
+
+/**
+ * Helper iterator to clean up nodemap on module exit.
+ *
+ * \param hs hash structure
+ * \param bd bucket descriptor
+ * \param hnode hash node
+ * \param data not used here
+ */
+static int nodemap_cleanup_iter_cb(cfs_hash_t *hs, cfs_hash_bd_t *bd,
+ cfs_hlist_node_t *hnode, void *data)
+{
+ struct lu_nodemap *nodemap;
+
+ nodemap = cfs_hlist_entry(hnode, struct lu_nodemap, nm_hash);
+ nodemap_putref(nodemap);
+
+ return 0;
+}
+
+/**
+ * Walk the nodemap_hash and remove all nodemaps.
+ */
+void nodemap_cleanup_all(void)
+{
+ cfs_hash_for_each_safe(nodemap_hash, nodemap_cleanup_iter_cb, NULL);
+ cfs_hash_putref(nodemap_hash);
+}
+
+/**
+ * Initialize nodemap_hash
+ *
+ * \retval 0 success
+ * \retval -ENOMEM cannot create hash
+ */
+static int nodemap_init_hash(void)
+{
+ nodemap_hash = cfs_hash_create("NODEMAP", HASH_NODEMAP_CUR_BITS,
+ HASH_NODEMAP_MAX_BITS,
+ HASH_NODEMAP_BKT_BITS, 0,
+ CFS_HASH_MIN_THETA,
+ CFS_HASH_MAX_THETA,
+ &nodemap_hash_operations,
+ CFS_HASH_DEFAULT);
+
+ if (nodemap_hash == NULL) {
+ CERROR("cannot create nodemap_hash table\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/**
+ * Check for valid nodemap name
+ *
+ * \param name nodemap name
+ * \retval true valid
+ * \retval false invalid
+ */
+static bool nodemap_name_is_valid(const char *name)
+{
+ for (; *name != '\0'; name++) {
+ if (!isalnum(*name) && *name != '_')
+ return false;
+ }
+ return true;
+}
+
+/**
+ * Nodemap lookup
+ *
+ * Look nodemap up in the nodemap hash
+ *
+ * \param name name of nodemap
+ * \paramA nodemap found nodemap or NULL
+ * \retval lu_nodemap named nodemap
+ * \retval NULL nodemap doesn't exist
+ */
+static int nodemap_lookup(const char *name, struct lu_nodemap **nodemap)
+{
+ int rc = 0;
+
+ if (!nodemap_name_is_valid(name))
+ GOTO(out, rc = -EINVAL);
+
+ *nodemap = cfs_hash_lookup(nodemap_hash, name);
+
+out:
+ return rc;
+}
+
+/**
+ * Nodemap constructor
+ *
+ * Creates an lu_nodemap structure and assigns sane default
+ * member values. If this is the default nodemap, the defaults
+ * are the most restictive in xterms of mapping behavior. Otherwise
+ * the default flags should be inherited from the default nodemap.
+ * The adds nodemap to nodemap_hash.
+ *
+ * \param name name of nodemap
+ * \param is_default true if default nodemap
+ * \retval 0 success
+ * \retval -EINVAL invalid nodemap name
+ * \retval -EEXIST nodemap already exists
+ * \retval -ENOMEM cannot allocate memory for nodemap
+ */
+static int nodemap_create(const char *name, bool is_default)
+{
+ struct lu_nodemap *nodemap = NULL;
+ int rc = 0;
+
+ rc = nodemap_lookup(name, &nodemap);
+ if (rc < 0)
+ goto out;
+
+ if (nodemap != NULL) {
+ nodemap_putref(nodemap);
+ GOTO(out, rc = -EEXIST);
+ }
+
+ OBD_ALLOC_PTR(nodemap);
+
+ if (nodemap == NULL) {
+ CERROR("cannot allocate memory (%zu bytes)"
+ "for nodemap '%s'\n", sizeof(*nodemap),
+ name);
+ GOTO(out, rc = -ENOMEM);
+ }
+
+ snprintf(nodemap->nm_name, sizeof(nodemap->nm_name), "%s", name);
+
+ INIT_LIST_HEAD(&(nodemap->nm_ranges));
+ nodemap->nm_local_to_remote_uidmap = RB_ROOT;
+ nodemap->nm_remote_to_local_uidmap = RB_ROOT;
+ nodemap->nm_local_to_remote_gidmap = RB_ROOT;
+ nodemap->nm_remote_to_local_gidmap = RB_ROOT;
+
+ if (is_default) {
+ nodemap->nm_id = LUSTRE_NODEMAP_DEFAULT_ID;
+ nodemap->nmf_trust_client_ids = 0;
+ nodemap->nmf_allow_root_access = 0;
+ nodemap->nmf_block_lookups = 0;
+
+ nodemap->nm_squash_uid = NODEMAP_NOBODY_UID;
+ nodemap->nm_squash_gid = NODEMAP_NOBODY_GID;
+
+ lprocfs_nodemap_register(name, is_default, nodemap);
+
+ default_nodemap = nodemap;
+ } else {
+ nodemap->nm_id = atomic_inc_return(&nodemap_highest_id);
+ nodemap->nmf_trust_client_ids =
+ default_nodemap->nmf_trust_client_ids;
+ nodemap->nmf_allow_root_access =
+ default_nodemap->nmf_allow_root_access;
+ nodemap->nmf_block_lookups =
+ default_nodemap->nmf_block_lookups;
+
+ nodemap->nm_squash_uid = default_nodemap->nm_squash_uid;
+ nodemap->nm_squash_gid = default_nodemap->nm_squash_gid;
+
+ lprocfs_nodemap_register(name, is_default, nodemap);
+ }
+
+ atomic_set(&nodemap->nm_refcount, 1);
+ rc = cfs_hash_add_unique(nodemap_hash, name, &nodemap->nm_hash);
+
+ if (rc == 0)
+ goto out;
+
+ CERROR("cannot add nodemap: '%s': rc = %d\n", name, rc);
+ nodemap_destroy(nodemap);
+
+out:
+ return rc;
+}
+
+/**
+ * Add a nodemap
+ *
+ * \param name name of nodemap
+ * \retval 0 success
+ * \retval -EINVAL invalid nodemap name
+ * \retval -EEXIST nodemap already exists
+ * \retval -ENOMEM cannot allocate memory for nodemap
+ */
+int nodemap_add(const char *name)
+{
+ return nodemap_create(name, 0);
+}
+EXPORT_SYMBOL(nodemap_add);
+
+/**
+ * Delete a nodemap
+ *
+ * \param name name of nodemmap
+ * \retval 0 success
+ * \retval -EINVAL invalid input
+ * \retval -ENOENT no existing nodemap
+ */
+int nodemap_del(const char *name)
+{
+ struct lu_nodemap *nodemap;
+ int rc = 0;
+
+ if (strcmp(name, DEFAULT_NODEMAP) == 0)
+ GOTO(out, rc = -EINVAL);
+
+ nodemap = cfs_hash_del_key(nodemap_hash, name);
+ if (nodemap == NULL)
+ GOTO(out, rc = -ENOENT);
+
+ nodemap_putref(nodemap);
+out:
+ return rc;
+}
+EXPORT_SYMBOL(nodemap_del);
+
+/**
+ * Cleanup nodemap module on exit
+ */
+static void nodemap_mod_exit(void)
+{
+ nodemap_cleanup_all();
+ lprocfs_remove(&proc_lustre_nodemap_root);
+}
+
+/**
+ * Initialize the nodemap module
+ */
+static int __init nodemap_mod_init(void)
+{
+ int rc = 0;
+
+ rc = nodemap_init_hash();
+ if (rc != 0)
+ goto cleanup;
+
+ nodemap_procfs_init();
+ rc = nodemap_create(DEFAULT_NODEMAP, 1);
+
+cleanup:
+ if (rc != 0)
+ nodemap_mod_exit();
+
+ return rc;
+}
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Lustre Client Nodemap Management Module");
+MODULE_AUTHOR("Joshua Walgenbach <jjw@iu.edu>");
+
+module_init(nodemap_mod_init);
+module_exit(nodemap_mod_exit);
--- /dev/null
+/*
+ * 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
+ */
+/*
+ * Copyright (C) 2013, Trustees of Indiana University
+ * Author: Joshua Walgenbach <jjw@iu.edu>
+ */
+
+#ifndef _NODEMAP_INTERNAL_H
+#define _NODEMAP_INTERNAL_H
+
+#include <lustre_nodemap.h>
+
+#define MODULE_STRING "nodemap"
+
+/* Default nobody uid and gid values */
+
+#define NODEMAP_NOBODY_UID 99
+#define NODEMAP_NOBODY_GID 99
+
+struct lprocfs_static_vars;
+
+/* nodemap root proc directory under fs/lustre */
+extern struct proc_dir_entry *proc_lustre_nodemap_root;
+/* flag if nodemap is active */
+extern bool nodemap_idmap_active;
+
+int nodemap_procfs_init(void);
+int lprocfs_nodemap_register(const char *name, bool is_default_nodemap,
+ struct lu_nodemap *nodemap);
+int nodemap_cleanup_nodemaps(void);
+#endif /* _NODEMAP_INTERNAL_H */
--- /dev/null
+/*
+ * 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
+ */
+/*
+ * Copyright (C) 2013, Trustees of Indiana University
+ * Author: Joshua Walgenbach <jjw@iu.edu>
+ */
+
+#define NODEMAP_LPROC_ID_LEN 16
+#define NODEMAP_LPROC_FLAG_LEN 2
+
+#include <lprocfs_status.h>
+#include <lustre_net.h>
+#include "nodemap_internal.h"
+
+static int nodemap_rd_active(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ int rc;
+
+ rc = snprintf(page, count, "%u\n", (unsigned int)nodemap_idmap_active);
+
+ if (count == 0)
+ return 0;
+
+ return rc;
+}
+
+static int nodemap_wr_active(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ char active_string[NODEMAP_LPROC_FLAG_LEN + 1];
+ __u32 active;
+ int rc = count;
+
+ if (count == 0)
+ return 0;
+
+ if (count > NODEMAP_LPROC_FLAG_LEN)
+ return -EINVAL;
+
+ if (copy_from_user(active_string, buffer, count))
+ return -EFAULT;
+
+ active_string[count] = '\0';
+ active = simple_strtoul(active_string, NULL, 10);
+ nodemap_idmap_active = active;
+
+ return rc;
+}
+
+static int nodemap_rd_id(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct lu_nodemap *nodemap = data;
+
+ return snprintf(page, count, "%u\n", nodemap->nm_id);
+}
+
+static int nodemap_rd_squash_uid(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct lu_nodemap *nodemap = data;
+
+ return snprintf(page, count, "%u\n", nodemap->nm_squash_uid);
+}
+
+static int nodemap_rd_squash_gid(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct lu_nodemap *nodemap = data;
+
+ return snprintf(page, count, "%u\n", nodemap->nm_squash_gid);
+}
+
+static int nodemap_rd_trusted(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ struct lu_nodemap *nodemap = data;
+
+ return snprintf(page, count, "%d\n",
+ (int)nodemap->nmf_trust_client_ids);
+}
+
+static int nodemap_rd_admin(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ struct lu_nodemap *nodemap = data;
+
+ return snprintf(page, count, "%d\n",
+ (int)nodemap->nmf_allow_root_access);
+}
+
+#ifdef NODEMAP_PROC_DEBUG
+static int nodemap_proc_read_flag(const char __user *buffer,
+ unsigned long count, unsigned int *flag_p)
+{
+ char scratch[NODEMAP_LPROC_FLAG_LEN + 1];
+
+ if (count == 0)
+ return 0;
+
+ if (count > NODEMAP_LPROC_FLAG_LEN)
+ return -EINVAL;
+
+ if (copy_from_user(scratch, buffer, count))
+ return -EFAULT;
+
+ scratch[count] = '\0';
+ *flag_p = simple_strtoul(scratch, NULL, 10);
+
+ return 0;
+}
+
+static int nodemap_wr_squash_uid(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ char squash[NODEMAP_LPROC_ID_LEN + 1];
+ struct lu_nodemap *nodemap = data;
+ uid_t squash_uid;
+ int rc = count;
+
+ if (count == 0)
+ return 0;
+
+ if (count > NODEMAP_LPROC_FLAG_LEN)
+ return -EINVAL;
+
+ if (copy_from_user(squash, buffer, count))
+ return -EFAULT;
+
+ squash[count] = '\0';
+ squash_uid = simple_strtoul(squash, NULL, 10);
+ nodemap->nm_squash_uid = squash_uid;
+
+ return rc;
+}
+
+static int nodemap_wr_squash_gid(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ char squash[NODEMAP_LPROC_ID_LEN + 1];
+ struct lu_nodemap *nodemap = data;
+ gid_t squash_gid;
+ int rc = count;
+
+ if (count == 0)
+ return 0;
+
+ if (count > NODEMAP_LPROC_FLAG_LEN)
+ return -EINVAL;
+
+ if (copy_from_user(squash, buffer, count))
+ return -EFAULT;
+
+ squash[count] = '\0';
+ squash_gid = simple_strtoul(squash, NULL, 10);
+ nodemap->nm_squash_gid = squash_gid;
+
+ return rc;
+}
+
+static int nodemap_wr_trusted(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ struct lu_nodemap *nodemap = data;
+ int flags;
+ int rc;
+
+ rc = nodemap_proc_read_flag(buffer, count, &flags);
+ if (rc == 0)
+ nodemap->nmf_trust_client_ids = !!flags;
+
+ return rc;
+}
+
+static int nodemap_wr_admin(struct file *file, const char __user *buffer,
+ unsigned long count, void *data)
+{
+ struct lu_nodemap *nodemap = data;
+ int flags;
+ int rc;
+
+ rc = nodemap_proc_read_flag(buffer, count, &flags);
+ if (rc == 0)
+ nodemap->nmf_allow_root_access = !!flags;
+
+ return rc;
+}
+
+static int nodemap_proc_add_nodemap(struct file *file,
+ const char __user *buffer,
+ unsigned long count, void *data)
+{
+ char buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
+ char *cpybuf = NULL;
+ char *name;
+ char *pos;
+ int rc = count;
+
+ if (count == 0)
+ return 0;
+
+ if (count > LUSTRE_NODEMAP_NAME_LENGTH)
+ return -EINVAL;
+
+ if (copy_from_user(buf, buffer, count))
+ return -EFAULT;
+
+ buf[count] = '\0';
+ pos = strchr(buf, '\n');
+ if (pos != NULL)
+ *pos = '\0';
+
+ cpybuf = buf;
+ name = strsep(&cpybuf, " ");
+ if (name == NULL)
+ return -EINVAL;
+
+ rc = nodemap_add(name);
+ if (rc == 0)
+ rc = count;
+
+ return rc;
+}
+
+static int nodemap_proc_del_nodemap(struct file *file,
+ const char __user *buffer,
+ unsigned long count, void *data)
+{
+ char buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
+ char *cpybuf = NULL;
+ char *name;
+ char *pos;
+ int rc = count;
+
+ if (count == 0)
+ return 0;
+
+ if (count > LUSTRE_NODEMAP_NAME_LENGTH)
+ return -EINVAL;
+
+ if (copy_from_user(buf, buffer, count))
+ return -EFAULT;
+
+ buf[count] = '\0';
+ pos = strchr(buf, '\n');
+ if (pos != NULL)
+ *pos = '\0';
+
+ cpybuf = buf;
+ name = strsep(&cpybuf, " ");
+ if (name == NULL)
+ return -EINVAL;
+
+ rc = nodemap_del(name);
+ if (rc == 0)
+ rc = count;
+
+ return rc;
+
+}
+#endif /* NODEMAP_PROC_DEBUG */
+
+static struct lprocfs_vars lprocfs_nodemap_module_vars[] = {
+ {
+ .name = "active",
+ .read_fptr = nodemap_rd_active,
+ .write_fptr = nodemap_wr_active,
+ },
+#ifdef NODEMAP_PROC_DEBUG
+ {
+ .name = "add_nodemap",
+ .write_fptr = nodemap_proc_add_nodemap,
+ },
+ {
+ .name = "remove_nodemap",
+ .write_fptr = nodemap_proc_del_nodemap,
+ },
+#endif /* NODEMAP_PROC_DEBUG */
+ {
+ NULL
+ }
+};
+
+#ifdef NODEMAP_PROC_DEBUG
+static struct lprocfs_vars lprocfs_nodemap_vars[] = {
+ {
+ .name = "id",
+ .read_fptr = nodemap_rd_id,
+ },
+ {
+ .name = "trusted_nodemap",
+ .read_fptr = nodemap_rd_trusted,
+ .write_fptr = nodemap_wr_trusted,
+ },
+ {
+ .name = "admin_nodemap",
+ .read_fptr = nodemap_rd_admin,
+ .write_fptr = nodemap_wr_admin,
+ },
+ {
+ .name = "squash_uid",
+ .read_fptr = nodemap_rd_squash_uid,
+ .write_fptr = nodemap_wr_squash_uid,
+ },
+ {
+ .name = "squash_gid",
+ .read_fptr = nodemap_rd_squash_gid,
+ .write_fptr = nodemap_wr_squash_gid,
+ },
+ {
+ NULL
+ }
+};
+
+static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
+ {
+ .name = "id",
+ .read_fptr = nodemap_rd_id,
+ },
+ {
+ .name = "trusted_nodemap",
+ .read_fptr = nodemap_rd_trusted,
+ .write_fptr = nodemap_wr_trusted,
+ },
+ {
+ .name = "admin_nodemap",
+ .read_fptr = nodemap_rd_admin,
+ .write_fptr = nodemap_wr_admin,
+ },
+ {
+ .name = "squash_uid",
+ .read_fptr = nodemap_rd_squash_uid,
+ .write_fptr = nodemap_wr_squash_uid,
+ },
+ {
+ .name = "squash_gid",
+ .read_fptr = nodemap_rd_squash_gid,
+ .write_fptr = nodemap_wr_squash_gid,
+ },
+ {
+ NULL
+ }
+};
+#else
+static struct lprocfs_vars lprocfs_nodemap_vars[] = {
+ {
+ .name = "id",
+ .read_fptr = nodemap_rd_id,
+ },
+ {
+ .name = "trusted_nodemap",
+ .read_fptr = nodemap_rd_trusted,
+ },
+ {
+ .name = "admin_nodemap",
+ .read_fptr = nodemap_rd_admin,
+ },
+ {
+ .name = "squash_uid",
+ .read_fptr = nodemap_rd_squash_uid,
+ },
+ {
+ .name = "squash_gid",
+ .read_fptr = nodemap_rd_squash_gid,
+ },
+ {
+ NULL
+ }
+};
+
+static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
+ {
+ .name = "id",
+ .read_fptr = nodemap_rd_id,
+ },
+ {
+ .name = "trusted_nodemap",
+ .read_fptr = nodemap_rd_trusted,
+ },
+ {
+ .name = "admin_nodemap",
+ .read_fptr = nodemap_rd_admin,
+ },
+ {
+ .name = "squash_uid",
+ .read_fptr = nodemap_rd_squash_uid,
+ },
+ {
+ .name = "squash_gid",
+ .read_fptr = nodemap_rd_squash_gid,
+ },
+ {
+ NULL
+ }
+};
+#endif /* NODEMAP_PROC_DEBUG */
+
+int nodemap_procfs_init(void)
+{
+ int rc = 0;
+
+ proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
+ proc_lustre_root,
+ lprocfs_nodemap_module_vars,
+ NULL);
+
+ if (IS_ERR(proc_lustre_nodemap_root)) {
+ rc = PTR_ERR(proc_lustre_nodemap_root);
+ CERROR("cannot create 'nodemap' directory: rc = %d\n",
+ rc);
+ proc_lustre_nodemap_root = NULL;
+ }
+
+ return rc;
+}
+
+/**
+ * Register the proc directory for a nodemap
+ *
+ * \param name name of nodemap
+ * \param is_default: 1 if default nodemap
+ * \retval 0 success
+ */
+int lprocfs_nodemap_register(const char *name,
+ bool is_default,
+ struct lu_nodemap *nodemap)
+{
+ struct proc_dir_entry *nodemap_proc_entry;
+ int rc = 0;
+
+ if (is_default)
+ nodemap_proc_entry =
+ lprocfs_register(name,
+ proc_lustre_nodemap_root,
+ lprocfs_default_nodemap_vars,
+ nodemap);
+ else
+ nodemap_proc_entry = lprocfs_register(name,
+ proc_lustre_nodemap_root,
+ lprocfs_nodemap_vars,
+ nodemap);
+
+ if (IS_ERR(nodemap_proc_entry)) {
+ rc = PTR_ERR(nodemap_proc_entry);
+ CERROR("cannot create 'nodemap/%s': rc = %d\n", name, rc);
+ nodemap_proc_entry = NULL;
+ }
+
+ nodemap->nm_proc_entry = nodemap_proc_entry;
+
+ return rc;
+}
PERM_CONF=$CONFDIR/perm.conf
FAIL_ON_ERROR=false
+HN=$(hostname | sum | awk '{ print $1 }')
+NODEMAP_COUNT=10
+NODEMAP_RANGE_COUNT=3
+NODEMAP_IPADDR_COUNT=30
+NODEMAP_ID_COUNT=200
+
require_dsh_mds || exit 0
require_dsh_ost || exit 0
}
run_test 6 "capa expiry ========================="
+create_nodemaps() {
+ local i
+ local out
+ local rc
+
+ for (( i = 0; i < NODEMAP_COUNT; i++ )); do
+ if ! do_facet mgs $LCTL nodemap_add ${HN}_${i}; then
+ return 1
+ fi
+ out=$(do_facet mgs $LCTL get_param nodemap.${HN}_${i}.id)
+ ## This needs to return zero if the following statement is 1
+ rc=$(echo $out | grep -c ${HN}_${i})
+ [[ $rc == 0 ]] && return 1
+ done
+ return 0
+}
+
+delete_nodemaps() {
+ local i
+ local out
+ local rc
+
+ for ((i = 0; i < NODEMAP_COUNT; i++)); do
+ if ! do_facet mgs $LCTL nodemap_del ${HN}_${i}; then
+ error "nodemap_del ${HN}_${i} failed with $rc"
+ return 3
+ fi
+ out=$(do_facet mgs $LCTL get_param nodemap.${HN}_${i}.id)
+ rc=$(echo $out | grep -c ${HN}_${i})
+ [[ $rc != 0 ]] && return 1
+ done
+ return 0
+}
+
+test_7() {
+ local rc
+
+ create_nodemaps
+ rc=$?
+ [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
+
+ delete_nodemaps
+ rc=$?
+ [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 2
+
+ return 0
+}
+run_test 7 "nodemap create and delete"
+
+test_8() {
+ local rc
+
+ # Set up nodemaps
+
+ create_nodemaps
+ rc=$?
+ [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 1
+
+ # Try duplicates
+
+ create_nodemaps
+ rc=$?
+ [[ $rc == 0 ]] && error "duplicate nodemap_add allowed with $rc" &&
+ return 2
+
+ # Clean up
+ delete_nodemaps
+ rc=$?
+ [[ $rc != 0 ]] && error "nodemap_add failed with $rc" && return 3
+
+ return 0
+}
+run_test 8 "nodemap reject duplicates"
+
log "cleanup: ======================================================"
sec_unsetup() {
load_module ../ldiskfs/ldiskfs
load_module osd-ldiskfs/osd_ldiskfs
fi
+ load_module nodemap/nodemap
load_module mgs/mgs
load_module mdd/mdd
load_module mdt/mdt
L_IOCTL := $(top_builddir)/libcfs/libcfs/util/l_ioctl.c
L_KERNELCOMM := $(top_builddir)/libcfs/libcfs/kernel_user_comm.c
liblustreapitmp_a_SOURCES = liblustreapi.c liblustreapi_hsm.c \
- lustreapi_internal.h \
+ liblustreapi_nodemap.c lustreapi_internal.h \
$(L_IOCTL) $(L_KERNELCOMM)
# build static and shared lib lustreapi
{"=== Pools ==", jt_noop, 0, "pool management"},
{"pool_new", jt_pool_cmd, 0,
"add a new pool\n"
- "usage pool_new <fsname>.<poolname>"},
- {"pool_add", jt_pool_cmd, 0,
+ "usage: pool_new <fsname>.<poolname>"},
+ {"pool_add", jt_pool_cmd, 0,
"add the named OSTs to the pool\n"
- "usage pool_add <fsname>.<poolname> <ostname indexed list>"},
+ "usage: pool_add <fsname>.<poolname> <ostname indexed list>"},
{"pool_remove", jt_pool_cmd, 0,
"remove the named OST from the pool\n"
- "usage pool_remove <fsname>.<poolname> <ostname indexed list>"},
+ "usage: pool_remove <fsname>.<poolname> <ostname indexed list>"},
{"pool_destroy", jt_pool_cmd, 0,
"destroy a pool\n"
- "usage pool_destroy <fsname>.<poolname>"},
+ "usage: pool_destroy <fsname>.<poolname>"},
{"pool_list", jt_pool_cmd, 0,
"list pools and pools members\n"
- "usage pool_list <fsname>[.<poolname>] | <pathname>"},
+ "usage: pool_list <fsname>[.<poolname>] | <pathname>"},
+
+ /* Nodemap commands */
+ {"=== Nodemap ===", jt_noop, 0, "nodemap management"},
+ {"nodemap_activate_idmap", jt_nodemap_activate, 0,
+ "activate nodemap idmapping functions\n"
+ "usage: nodemap_activate_idmap"},
+ {"nodemap_add", jt_nodemap_add, 0,
+ "add a new nodemap\n"
+ "usage: nodemap_add <nodemap_name>"},
+ {"nodemap_del", jt_nodemap_del, 0,
+ "remove a nodemap\n"
+ "usage: nodemap_del <nodemap_name>"},
/* Changelog commands */
{"=== Changelogs ==", jt_noop, 0, "changelog user management"},
* Return 0 for success, with a NUL-terminated string in \param result.
* Return -ve value for error.
*/
-static int get_param(const char *param_path, char *result,
+int get_param(const char *param_path, char *result,
unsigned int result_size)
{
char file[PATH_MAX + 1], pattern[PATH_MAX + 1], buf[result_size];
snprintf(pattern, PATH_MAX, "/proc/{fs,sys}/{lnet,lustre}/%s",
param_path);
rc = first_match(pattern, file);
- if (rc)
+ if (rc != 0 || result == NULL)
return rc;
fp = fopen(file, "r");
--- /dev/null
+/*
+ * LGPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 or (at your discretion) any later version.
+ * (LGPL) version 2.1 accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl-2.1.html
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * LGPL HEADER END
+ */
+/*
+ * Copyright (C) 2013, Trustees of Indiana University
+ * Author: Joshua Walgenbach <jjw@iu.edu>
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <liblustre.h>
+#include <lustre/lustreapi.h>
+#include "lustreapi_internal.h"
+
+int llapi_nodemap_exists(const char *nodemap)
+{
+ char mapname[PATH_MAX + 1];
+
+ snprintf(mapname, sizeof(mapname) - 1, "nodemap/%s", nodemap);
+
+ return get_param(mapname, NULL, 0);
+}
int get_root_path(int want, char *fsname, int *outfd, char *path, int index);
int root_ioctl(const char *mdtname, int opc, void *data, int *mdtidxp,
int want_error);
-
+int get_param(const char *param_path, char *result,
+ unsigned int result_size);
#endif /* _LUSTREAPI_INTERNAL_H_ */
return rc;
}
+static int nodemap_cmd(enum lcfg_command_type cmd, int num_args, ...)
+{
+ va_list arguments;
+ int i;
+ const char *args;
+ char *arg;
+ struct lustre_cfg_bufs bufs;
+ struct obd_ioctl_data data;
+ struct lustre_cfg *lcfg;
+ char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
+ int rc = 0;
+
+ lustre_cfg_bufs_reset(&bufs, NULL);
+
+ va_start(arguments, num_args);
+
+ for (i = 0; i < num_args; i++) {
+ args = va_arg(arguments, char *);
+ arg = (char *)args;
+ lustre_cfg_bufs_set_string(&bufs, i, arg);
+ }
+
+ va_end(arguments);
+
+ lcfg = lustre_cfg_new(cmd, &bufs);
+
+ if (IS_ERR(lcfg)) {
+ rc = PTR_ERR(lcfg);
+ return rc;
+ }
+
+ memset(&data, 0, sizeof(data));
+ rc = data.ioc_dev = get_mgs_device();
+ if (rc < 0)
+ goto out;
+
+ data.ioc_type = LUSTRE_CFG_TYPE;
+ data.ioc_plen1 = lustre_cfg_len(lcfg->lcfg_bufcount,
+ lcfg->lcfg_buflens);
+ data.ioc_pbuf1 = (void *)lcfg;
+
+ memset(buf, 0, sizeof(rawbuf));
+ rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
+ if (rc) {
+ fprintf(stderr, "error: invalid ioctl\n");
+ return rc;
+ }
+ rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NODEMAP, buf);
+out:
+ if (rc)
+ rc = -errno;
+
+ lustre_cfg_free(lcfg);
+ return rc;
+}
+
+int jt_nodemap_activate(int argc, char **argv)
+{
+ enum lcfg_command_type cmd;
+ int rc = 0;
+
+ cmd = LCFG_NODEMAP_ACTIVATE;
+ rc = nodemap_cmd(cmd, 1, argv[0]);
+
+ if (rc != 0) {
+ errno = -rc;
+ perror(argv[0]);
+ }
+
+ return rc;
+}
+
+int jt_nodemap_add(int argc, char **argv)
+{
+ enum lcfg_command_type cmd;
+ int rc = 0;
+
+ cmd = LCFG_NODEMAP_ADD;
+ rc = llapi_nodemap_exists(argv[1]);
+ if (rc == 0) {
+ fprintf(stderr, "error: %s existing nodemap name\n", argv[1]);
+ return 1;
+ }
+
+ rc = nodemap_cmd(cmd, 2, argv[0], argv[1]);
+
+ if (rc != 0) {
+ errno = -rc;
+ perror(argv[0]);
+ }
+
+ return rc;
+}
+
+int jt_nodemap_del(int argc, char **argv)
+{
+ enum lcfg_command_type cmd;
+ int rc = 0;
+
+ cmd = LCFG_NODEMAP_DEL;
+ rc = llapi_nodemap_exists(argv[1]);
+
+ if (rc != 0) {
+ fprintf(stderr, "error: %s not existing nodemap name\n",
+ argv[1]);
+ return rc;
+ }
+ rc = nodemap_cmd(cmd, 2, argv[0], argv[1]);
+
+ if (rc != 0) {
+ errno = -rc;
+ perror(argv[0]);
+ }
+
+ return rc;
+}
+
/*
* this function tranforms a rule [start-end/step] into an array
* of matching numbers
int jt_blockdev_info(int argc, char **argv);
int jt_pool_cmd(int argc, char **argv);
+int jt_nodemap_activate(int argc, char **argv);
+int jt_nodemap_add(int argc, char **argv);
+int jt_nodemap_del(int argc, char **argv);
int jt_changelog_register(int argc, char **argv);
int jt_changelog_deregister(int argc, char **argv);