#include <unistd.h>
#include "obdctl.h"
-
-#include <obd.h> /* for struct lov_stripe_md */
+#include <libcfs/libcfs.h>
+#include <lnet/lnet.h>
+#include <lustre/lustre_idl.h>
+#include <lustre_cfg.h>
+#include <lustre_ioctl.h>
#include <lustre/lustre_build_version.h>
#include <lnet/lnetctl.h>
#define MAX_THREADS 4096
#define MAX_BASE_ID 0xffffffff
+#define NIDSTRING_LENGTH 64
struct shared_data {
l_mutex_t mutex;
l_cond_t cond;
static int cur_device = -1;
-struct lov_oinfo lov_oinfos[LOV_MAX_STRIPE_COUNT];
-
-struct lsm_buffer {
- struct lov_stripe_md lsm;
- struct lov_oinfo *ptrs[LOV_MAX_STRIPE_COUNT];
-} lsm_buffer;
-
static int l2_ioctl(int dev_id, int opc, void *buf)
{
return l_ioctl(dev_id, opc, buf);
return ret;
}
-static void
-reset_lsmb (struct lsm_buffer *lsmb)
-{
- memset (&lsmb->lsm, 0, sizeof (lsmb->lsm));
- memset(lov_oinfos, 0, sizeof(lov_oinfos));
- lsmb->lsm.lsm_magic = LOV_MAGIC;
-}
-
-static int
-parse_lsm (struct lsm_buffer *lsmb, char *string)
-{
- struct lov_stripe_md *lsm = &lsmb->lsm;
- char *end;
- int i;
-
- /*
- * object_id[=size#count[@offset:id]*]
- */
-
- reset_lsmb (lsmb);
-
- ostid_set_id(&lsm->lsm_oi, strtoull(string, &end, 0));
- if (end == string)
- return -1;
- string = end;
-
- if (*string == 0)
- return (0);
-
- if (*string != '=')
- return (-1);
- string++;
-
- lsm->lsm_stripe_size = strtoul (string, &end, 0);
- if (end == string)
- return (-1);
- string = end;
-
- if (*string != '#')
- return (-1);
- string++;
-
- lsm->lsm_stripe_count = strtoul (string, &end, 0);
- if (end == string)
- return (-1);
- string = end;
-
- if (*string == 0) /* don't have to specify obj ids */
- return (0);
-
- for (i = 0; i < lsm->lsm_stripe_count; i++) {
- if (*string != '@')
- return (-1);
- string++;
- lsm->lsm_oinfo[i]->loi_ost_idx = strtoul(string, &end, 0);
- if (*end != ':')
- return (-1);
- string = end + 1;
- ostid_set_id(&lsm->lsm_oinfo[i]->loi_oi,
- strtoull(string, &end, 0));
- string = end;
- }
-
- if (*string != 0)
- return (-1);
-
- return (0);
-}
-
char *jt_cmdname(char *func)
{
static char buf[512];
rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);
if (rc != 0) {
fprintf(stderr, "Can't set shared mutex attr\n");
- return rc;
+ goto out;
}
rc = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);
if (rc != 0) {
fprintf(stderr, "Can't set shared cond attr\n");
- return rc;
+ goto out;
}
pthread_mutex_init(&shared_data->mutex, &mattr);
pthread_cond_init(&shared_data->cond, &cattr);
-
+out:
pthread_mutexattr_destroy(&mattr);
pthread_condattr_destroy(&cattr);
- return 0;
+ return rc;
}
static inline void shmem_lock(void)
return jt_obd_md_common(argc, argv, ECHO_MD_GETATTR);
}
-/* Create one or more objects, arg[4] may describe stripe meta-data. If
- * not, defaults assumed. This echo-client instance stashes the stripe
- * object ids. Use get_stripe on this node to print full lsm and
- * set_stripe on another node to cut/paste between nodes.
- */
-/* create <count> [<file_create_mode>] [q|v|# verbosity] [striping] */
int jt_obd_create(int argc, char **argv)
{
- char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
- struct obd_ioctl_data data;
- struct timeval next_time;
- __u64 count = 1, next_count, base_id = 1;
- int verbose = 1, mode = 0100644, rc = 0, i, valid_lsm = 0;
+ char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
+ struct obd_ioctl_data data;
+ struct timeval next_time;
+ __u64 count = 1, next_count, base_id = 1;
+ int verbose = 1, mode = 0100644, rc = 0, i;
char *end;
memset(&data, 0, sizeof(data));
data.ioc_dev = cur_device;
- if (argc < 2 || argc > 5)
- return CMD_HELP;
+ if (argc < 2 || argc > 4)
+ return CMD_HELP;
count = strtoull(argv[1], &end, 0);
if (*end) {
return CMD_HELP;
}
- if (argc < 5) {
- reset_lsmb(&lsm_buffer); /* will set default */
- } else {
- rc = parse_lsm(&lsm_buffer, argv[4]);
- if (rc != 0) {
- fprintf(stderr, "error: %s: invalid lsm '%s'\n",
- jt_cmdname(argv[0]), argv[4]);
- return CMD_HELP;
- }
- base_id = ostid_id(&lsm_buffer.lsm.lsm_oi);
- valid_lsm = 1;
- }
-
printf("%s: "LPD64" objects\n", jt_cmdname(argv[0]), count);
gettimeofday(&next_time, NULL);
next_time.tv_sec -= verbose;
data.ioc_obdo1.o_valid = OBD_MD_FLTYPE | OBD_MD_FLMODE |
OBD_MD_FLID | OBD_MD_FLUID |
OBD_MD_FLGID | OBD_MD_FLGROUP;
- if (valid_lsm) {
- data.ioc_plen1 = sizeof lsm_buffer;
- data.ioc_pbuf1 = (char *)&lsm_buffer;
- }
memset(buf, 0, sizeof(rawbuf));
rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
return rc;
}
-int jt_obd_ldlm_regress_start(int argc, char **argv)
-{
- int rc;
- struct obd_ioctl_data data;
- char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
- char argstring[200];
- int i, count = sizeof(argstring) - 1;
-
- memset(&data, 0, sizeof(data));
- data.ioc_dev = cur_device;
- if (argc > 5)
- return CMD_HELP;
-
- argstring[0] = '\0';
- for (i = 1; i < argc; i++) {
- strncat(argstring, " ", count);
- count--;
- strncat(argstring, argv[i], count);
- count -= strlen(argv[i]);
- }
-
- if (strlen(argstring)) {
- data.ioc_inlbuf1 = argstring;
- data.ioc_inllen1 = strlen(argstring) + 1;
- }
-
- memset(buf, 0, sizeof(rawbuf));
- rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
- if (rc) {
- fprintf(stderr, "error: %s: invalid ioctl\n",
- jt_cmdname(argv[0]));
- return rc;
- }
- rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_START, buf);
- if (rc)
- fprintf(stderr, "error: %s: test failed: %s\n",
- jt_cmdname(argv[0]), strerror(rc = errno));
-
- return rc;
-}
-
-int jt_obd_ldlm_regress_stop(int argc, char **argv)
-{
- int rc;
- char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf;
- struct obd_ioctl_data data;
-
- memset(&data, 0, sizeof(data));
- data.ioc_dev = cur_device;
-
- if (argc != 1)
- return CMD_HELP;
-
- memset(buf, 0, sizeof(rawbuf));
- rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
- if (rc) {
- fprintf(stderr, "error: %s: invalid ioctl\n",
- jt_cmdname(argv[0]));
- return rc;
- }
- rc = l2_ioctl(OBD_DEV_ID, IOC_LDLM_REGRESS_STOP, buf);
-
- if (rc)
- fprintf(stderr, "error: %s: test failed: %s\n",
- jt_cmdname(argv[0]), strerror(rc = errno));
- return rc;
-}
-
static int do_activate(int argc, char **argv, int flag)
{
struct obd_ioctl_data data;
int obd_initialize(int argc, char **argv)
{
- int i;
-
- for (i = 0; i < LOV_MAX_STRIPE_COUNT; i++)
- lsm_buffer.lsm.lsm_oinfo[i] = lov_oinfos + i;
-
- if (shmem_setup() != 0)
- return -1;
+ if (shmem_setup() != 0)
+ return -1;
- register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH,
- OBD_DEV_MAJOR, OBD_DEV_MINOR);
+ register_ioc_dev(OBD_DEV_ID, OBD_DEV_PATH,
+ OBD_DEV_MAJOR, OBD_DEV_MINOR);
- return 0;
+ return 0;
}
void obd_finalize(int argc, char **argv)
return rc;
}
+/**
+ * Format and send the ioctl to the MGS.
+ *
+ * \param cmd IOCTL to send
+ * \param ret_data void pointer to return anything from
+ * ioctl
+ * \param num_args number of arguments to pack into the
+ * ioctl buffer
+ * \param argv[] variable number of string arguments
+ *
+ * \retval 0 on success
+ */
+static int nodemap_cmd(enum lcfg_command_type cmd, void *ret_data,
+ unsigned int ret_size, ...)
+{
+ va_list ap;
+ char *arg;
+ int i = 0;
+ struct lustre_cfg_bufs bufs;
+ struct obd_ioctl_data data;
+ struct lustre_cfg *lcfg;
+ char rawbuf[MAX_IOC_BUFLEN];
+ char *buf = rawbuf;
+ int rc = 0;
+
+ lustre_cfg_bufs_reset(&bufs, NULL);
+
+ va_start(ap, ret_size);
+ arg = va_arg(ap, char *);
+ while (arg != NULL) {
+ lustre_cfg_bufs_set_string(&bufs, i, arg);
+ i++;
+ arg = va_arg(ap, char *);
+ }
+ va_end(ap);
+
+ 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 != 0) {
+ fprintf(stderr, "error: invalid ioctl: %08x errno: %d with "
+ "rc=%d\n", cmd, errno, rc);
+ goto out;
+ }
+
+ rc = l_ioctl(OBD_DEV_ID, OBD_IOC_NODEMAP, buf);
+ if (rc != 0) {
+ fprintf(stderr, "error: invalid ioctl: %08x errno: %d with "
+ "rc=%d\n", cmd, errno, rc);
+ goto out;
+ }
+
+ if (ret_data != NULL) {
+ rc = obd_ioctl_unpack(&data, buf, sizeof(rawbuf));
+ if (rc != 0)
+ goto out;
+
+ memcpy(ret_data, data.ioc_pbuf1, data.ioc_plen1);
+ if (ret_data == NULL || sizeof(ret_data) != ret_size)
+ rc = -errno;
+ }
+out:
+ lustre_cfg_free(lcfg);
+
+ return rc;
+}
+
+/**
+ * activate nodemap functions
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * argv[0] 1 for activate or 0 for deactivate
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_activate(int argc, char **argv)
+{
+ int rc;
+
+ rc = nodemap_cmd(LCFG_NODEMAP_ACTIVATE, NULL, 0, argv[0], argv[1],
+ NULL);
+
+ if (rc != 0) {
+ errno = -rc;
+ perror(argv[0]);
+ }
+
+ return rc;
+}
+
+/**
+ * add a nodemap
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * argv[0] nodemap name
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_add(int argc, char **argv)
+{
+ int rc;
+
+ rc = llapi_nodemap_exists(argv[1]);
+ if (rc == 0) {
+ fprintf(stderr, "error: %s existing nodemap name\n", argv[1]);
+ return 1;
+ }
+
+ rc = nodemap_cmd(LCFG_NODEMAP_ADD, NULL, 0, argv[0], argv[1], NULL);
+
+ if (rc != 0) {
+ errno = -rc;
+ perror(argv[0]);
+ }
+
+ return rc;
+}
+
+/**
+ * delete a nodemap
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * argv[0] nodemap name
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_del(int argc, char **argv)
+{
+ int rc;
+
+ 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(LCFG_NODEMAP_DEL, NULL, 0, argv[0], argv[1], NULL);
+
+ if (rc != 0) {
+ errno = -rc;
+ perror(argv[0]);
+ }
+
+ return rc;
+}
+
+/**
+ * test a nid for nodemap membership
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * argv[0] properly formatted nid
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_test_nid(int argc, char **argv)
+{
+
+ char rawbuf[MAX_IOC_BUFLEN];
+ int rc;
+
+ rc = nodemap_cmd(LCFG_NODEMAP_TEST_NID, &rawbuf, sizeof(rawbuf),
+ argv[0], argv[1], NULL);
+ if (rc == 0)
+ printf("%s\n", (char *)rawbuf);
+
+ return rc;
+}
+
+/**
+ * test a nodemap id pair for mapping
+ *
+ * \param argc number of args
+ * \param argv[[] variable string arguments
+ *
+ * \retval 0 on success
+ *
+ * The argv array should contain the nodemap name, the id
+ * to checking the mapping on, and the id type (UID or GID)
+ *
+ */
+int jt_nodemap_test_id(int argc, char **argv)
+{
+ char rawbuf[MAX_IOC_BUFLEN];
+ char *nidstr = NULL;
+ char *idstr = NULL;
+ char *typestr = NULL;
+ int rc = 0;
+ int c;
+
+ static struct option long_options[] = {
+ {
+ .name = "nid",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'n',
+ },
+ {
+ .name = "idtype",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 't',
+ },
+ {
+ .name = "id",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'i',
+ },
+ {
+ NULL
+ }
+ };
+
+ while ((c = getopt_long(argc, argv, "n:t:i:",
+ long_options, NULL)) != -1) {
+ switch (c) {
+ case 'n':
+ nidstr = optarg;
+ break;
+ case 't':
+ typestr = optarg;
+ break;
+ case 'i':
+ idstr = optarg;
+ break;
+ }
+ }
+
+ if (nidstr == NULL || typestr == NULL || idstr == NULL) {
+ fprintf(stderr, "usage: nodemap_test_id --nid <nid> "
+ "--idtype [uid|gid] --id <id>\n");
+ return -1;
+ }
+
+ rc = nodemap_cmd(LCFG_NODEMAP_TEST_ID, &rawbuf, sizeof(rawbuf),
+ argv[0], nidstr, typestr, idstr);
+ if (rc == 0)
+ printf("%s\n", (char *)rawbuf);
+
+ return rc;
+}
+
+/**
+ * add an nid range to a nodemap
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * --name nodemap name
+ * --range properly formatted nid range
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_add_range(int argc, char **argv)
+{
+ char *nodemap_name = NULL;
+ char *nodemap_range = NULL;
+ struct list_head nidlist;
+ char min_nid[LNET_NIDSTR_SIZE + 1];
+ char max_nid[LNET_NIDSTR_SIZE + 1];
+ char nid_range[2 * LNET_NIDSTR_SIZE + 2];
+ int rc = 0;
+ int c;
+
+ static struct option long_options[] = {
+ {
+ .name = "name",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'n',
+ },
+ {
+ .name = "range",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'r',
+ },
+ {
+ NULL
+ }
+ };
+
+ INIT_LIST_HEAD(&nidlist);
+
+ while ((c = getopt_long(argc, argv, "n:r:",
+ long_options, NULL)) != -1) {
+ switch (c) {
+ case 'n':
+ nodemap_name = optarg;
+ break;
+ case 'r':
+ nodemap_range = optarg;
+ break;
+ }
+ }
+
+ if (nodemap_name == NULL || nodemap_range == NULL) {
+ fprintf(stderr, "usage: nodemap_add_range --name <name> "
+ "--range <range>\n");
+ return -1;
+ }
+
+ if (cfs_parse_nidlist(nodemap_range, strlen(nodemap_range),
+ &nidlist) <= 0) {
+ fprintf(stderr, "error: %s: can't parse nid range: %s\n",
+ jt_cmdname(argv[0]), nodemap_range);
+ return -1;
+ }
+
+ if (!cfs_nidrange_is_contiguous(&nidlist)) {
+ fprintf(stderr, "error: %s: nodemap ranges must be "
+ "contiguous\n", jt_cmdname(argv[0]));
+ return -1;
+ }
+
+ cfs_nidrange_find_min_max(&nidlist, &min_nid[0], &max_nid[0],
+ LNET_NIDSTR_SIZE);
+ snprintf(nid_range, sizeof(nid_range), "%s:%s", min_nid, max_nid);
+
+ rc = nodemap_cmd(LCFG_NODEMAP_ADD_RANGE, NULL, 0, argv[0],
+ nodemap_name, nid_range, NULL);
+ if (rc != 0) {
+ errno = -rc;
+ fprintf(stderr, "error: %s: cannot add range '%s' to nodemap "
+ "'%s': rc = %d\n",
+ jt_cmdname(argv[0]), nodemap_range, nodemap_name, rc);
+ }
+
+ return rc;
+}
+
+/**
+ * delete an nid range to a nodemap
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * --name nodemap name
+ * --range properly formatted nid range
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_del_range(int argc, char **argv)
+{
+ char *nodemap_name = NULL;
+ char *nodemap_range = NULL;
+ struct list_head nidlist;
+ char min_nid[LNET_NIDSTR_SIZE + 1];
+ char max_nid[LNET_NIDSTR_SIZE + 1];
+ char nid_range[2 * LNET_NIDSTR_SIZE + 2];
+ int rc = 0;
+ int c;
+
+ static struct option long_options[] = {
+ {
+ .name = "name",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'n',
+ },
+ {
+ .name = "range",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'r',
+ },
+ {
+ NULL
+ }
+ };
+
+ INIT_LIST_HEAD(&nidlist);
+
+ while ((c = getopt_long(argc, argv, "n:r:",
+ long_options, NULL)) != -1) {
+ switch (c) {
+ case 'n':
+ nodemap_name = optarg;
+ break;
+ case 'r':
+ nodemap_range = optarg;
+ break;
+ }
+ }
+
+ if (nodemap_name == NULL || nodemap_range == NULL) {
+ fprintf(stderr, "usage: nodemap_del_range --name <name> "
+ "--range <range>\n");
+ return -1;
+ }
+
+ if (cfs_parse_nidlist(nodemap_range, strlen(nodemap_range),
+ &nidlist) <= 0) {
+ fprintf(stderr, "error: %s: can't parse nid range: %s\n",
+ jt_cmdname(argv[0]), nodemap_range);
+ return -1;
+ }
+
+ if (!cfs_nidrange_is_contiguous(&nidlist)) {
+ fprintf(stderr, "error: %s: nodemap ranges must be "
+ "contiguous\n", jt_cmdname(argv[0]));
+ return -1;
+ }
+
+ cfs_nidrange_find_min_max(&nidlist, &min_nid[0], &max_nid[0],
+ LNET_NIDSTR_SIZE);
+ snprintf(nid_range, sizeof(nid_range), "%s:%s", min_nid, max_nid);
+
+ rc = nodemap_cmd(LCFG_NODEMAP_DEL_RANGE, NULL, 0, argv[0],
+ nodemap_name, nid_range, NULL);
+ if (rc != 0) {
+ errno = -rc;
+ fprintf(stderr, "error: %s: cannot delete range '%s' to "
+ "nodemap '%s': rc = %d\n",
+ jt_cmdname(argv[0]), nodemap_range, nodemap_name, rc);
+ }
+
+ return rc;
+}
+
+/**
+ * modify a nodemap's behavior
+ *
+ * \param argc number of args
+ * \param argv[] variable string arguments
+ *
+ * --name nodemap name
+ * --property nodemap property to change
+ * admin, trusted, squash_uid, squash_gid)
+ * --value value to set property
+ *
+ * \retval 0 on success
+ */
+int jt_nodemap_modify(int argc, char **argv)
+{
+ int c;
+ int rc = 0;
+ enum lcfg_command_type cmd = 0;
+ char *nodemap_name = NULL;
+ char *param = NULL;
+ char *value = NULL;
+
+ static struct option long_options[] = {
+ {
+ .name = "name",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'n',
+ },
+ {
+ .name = "property",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'p',
+ },
+ {
+ .name = "value",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'v',
+ },
+ {
+ NULL
+ }
+ };
+
+ while ((c = getopt_long(argc, argv, "n:p:v:",
+ long_options, NULL)) != -1) {
+ switch (c) {
+ case 'n':
+ nodemap_name = optarg;
+ break;
+ case 'p':
+ param = optarg;
+ break;
+ case 'v':
+ value = optarg;
+ break;
+ }
+ }
+
+ if (nodemap_name == NULL || param == NULL || value == NULL) {
+ fprintf(stderr, "usage: nodemap_modify --name <name> "
+ "--property <range> --value <value>\n");
+ return -1;
+ }
+
+ if (strcmp("admin", param) == 0) {
+ cmd = LCFG_NODEMAP_ADMIN;
+ } else if (strcmp("trusted", param) == 0) {
+ cmd = LCFG_NODEMAP_TRUSTED;
+ } else if (strcmp("squash_uid", param) == 0) {
+ cmd = LCFG_NODEMAP_SQUASH_UID;
+ } else if (strcmp("squash_gid", param) == 0) {
+ cmd = LCFG_NODEMAP_SQUASH_GID;
+ } else {
+ fprintf(stderr, "error: %s: nodemap_modify invalid "
+ "subcommand: %s\n",
+ jt_cmdname(argv[0]), param);
+ return -1;
+ }
+
+ rc = nodemap_cmd(cmd, NULL, 0, argv[0], nodemap_name, param,
+ value, NULL);
+ if (rc != 0) {
+ errno = -rc;
+ fprintf(stderr, "error: %s: cannot modify nodemap '%s' "
+ "to param '%s': value '%s': rc = %d\n",
+ jt_cmdname(argv[0]), nodemap_name, param, value, rc);
+ }
+
+ return rc;
+}
+
+int jt_nodemap_add_idmap(int argc, char **argv)
+{
+ int c;
+ enum lcfg_command_type cmd = 0;
+ char *nodemap_name = NULL;
+ char *idmap = NULL;
+ char *idtype = NULL;
+ int rc = 0;
+
+ static struct option long_options[] = {
+ {
+ .name = "name",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'n',
+ },
+ {
+ .name = "idmap",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'm',
+ },
+ {
+ .name = "idtype",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'i',
+ },
+ {
+ NULL
+ }
+ };
+
+ while ((c = getopt_long(argc, argv, "n:m:i:",
+ long_options, NULL)) != -1) {
+ switch (c) {
+ case 'n':
+ nodemap_name = optarg;
+ break;
+ case 'm':
+ idmap = optarg;
+ break;
+ case 'i':
+ idtype = optarg;
+ break;
+ }
+ }
+
+ if (nodemap_name == NULL || idmap == NULL || idtype == NULL) {
+ fprintf(stderr, "usage: %s --name <name> --idtype [uid | gid]"
+ " --idmap <client id>:<filesystem id>\n", argv[0]);
+ return -1;
+ }
+
+ if (strcmp("uid", idtype) == 0) {
+ cmd = LCFG_NODEMAP_ADD_UIDMAP;
+ } else if (strcmp("gid", idtype) == 0) {
+ cmd = LCFG_NODEMAP_ADD_GIDMAP;
+ } else {
+ fprintf(stderr, "usage: %s --name <name> --idtype [uid | gid]"
+ " --idmap <client id>:<filesystem id>\n", argv[0]);
+ return -1;
+ }
+
+ rc = nodemap_cmd(cmd, NULL, 0, argv[0], nodemap_name, idmap, NULL);
+ if (rc != 0) {
+ errno = -rc;
+ fprintf(stderr, "cannot add %smap '%s' to nodemap '%s'"
+ ": rc = %d\n", idtype, idmap, nodemap_name, rc);
+ }
+
+ return rc;
+}
+
+int jt_nodemap_del_idmap(int argc, char **argv)
+{
+ int c;
+ enum lcfg_command_type cmd = 0;
+ char *nodemap_name = NULL;
+ char *idmap = NULL;
+ char *idtype = NULL;
+ int rc = 0;
+
+ static struct option long_options[] = {
+ {
+ .name = "name",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'n',
+ },
+ {
+ .name = "idmap",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'm',
+ },
+ {
+ .name = "idtype",
+ .has_arg = required_argument,
+ .flag = 0,
+ .val = 'i',
+ },
+ {
+ NULL
+ }
+ };
+
+ while ((c = getopt_long(argc, argv, "n:m:i:",
+ long_options, NULL)) != -1) {
+ switch (c) {
+ case 'n':
+ nodemap_name = optarg;
+ break;
+ case 'm':
+ idmap = optarg;
+ break;
+ case 'i':
+ idtype = optarg;
+ break;
+ }
+ }
+
+ if (nodemap_name == NULL || idmap == NULL || idtype == NULL) {
+ fprintf(stderr, "usage: %s --name <name> --idtype [uid | gid]"
+ " --idmap <client id>:<filesystem id>\n", argv[0]);
+ return -1;
+ }
+
+ if (strcmp("uid", idtype) == 0)
+ cmd = LCFG_NODEMAP_DEL_UIDMAP;
+ else
+ cmd = LCFG_NODEMAP_DEL_GIDMAP;
+
+ rc = nodemap_cmd(cmd, NULL, 0, argv[0], nodemap_name, idmap, NULL);
+ if (rc != 0) {
+ errno = -rc;
+ fprintf(stderr, "cannot add %smap '%s' to nodemap '%s'"
+ ": rc = %d\n", idtype, idmap, nodemap_name, rc);
+ }
+
+ return rc;
+}
+
/*
* this function tranforms a rule [start-end/step] into an array
* of matching numbers