Whamcloud - gitweb
LU-17431 nodemap: allow handling an id map for a dynamic nm 09/54509/19
authorSebastien Buisson <sbuisson@ddn.com>
Wed, 20 Mar 2024 15:50:54 +0000 (16:50 +0100)
committerOleg Drokin <green@whamcloud.com>
Sun, 2 Feb 2025 06:22:49 +0000 (06:22 +0000)
Adding or deleting an id map for a dynamic nodemap, by sending the
appropriate ioctl to the MDS or OSS device.
On kernel side, we need to allow handling an idmap for a nodemap even
if the nodemap config file is not accessible (i.e. we are not on the
MGS). This dynamic nodemap is not stored on disk.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I055cf1d67b72a6bca5140814c4346ac578f2f31d
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54509
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Marc Vef <mvef@whamcloud.com>
lustre/ptlrpc/nodemap_handler.c
lustre/ptlrpc/nodemap_storage.c
lustre/tests/sanity-sec.sh
lustre/utils/lctl.c
lustre/utils/obd.c

index 2238a57..34995b6 100644 (file)
@@ -550,7 +550,8 @@ int nodemap_add_idmap_helper(struct lu_nodemap *nodemap,
 
                del_map[0] = temp->id_client;
                idmap_delete(id_type, temp, nodemap);
-               rc = nodemap_idx_idmap_del(nodemap, id_type, del_map);
+               if (!nodemap->nm_dyn)
+                       rc = nodemap_idx_idmap_del(nodemap, id_type, del_map);
                /* In case there is any corrupted idmap */
                if (!rc || unlikely(rc == -ENOENT)) {
                        temp = idmap_insert(id_type, idmap, nodemap);
@@ -609,7 +610,7 @@ int nodemap_add_idmap(const char *nodemap_name, enum nodemap_id_type id_type,
                GOTO(out_unlock, rc = -EPERM);
 
        rc = nodemap_add_idmap_helper(nodemap, id_type, map);
-       if (!rc)
+       if (!rc && !nodemap->nm_dyn)
                rc = nodemap_idx_idmap_add(nodemap, id_type, map);
 
 out_unlock:
@@ -660,7 +661,8 @@ int nodemap_del_idmap(const char *nodemap_name, enum nodemap_id_type id_type,
                rc = -EINVAL;
        } else {
                idmap_delete(id_type, idmap, nodemap);
-               rc = nodemap_idx_idmap_del(nodemap, id_type, map);
+               if (!nodemap->nm_dyn)
+                       rc = nodemap_idx_idmap_del(nodemap, id_type, map);
        }
        up_write(&nodemap->nm_idmap_lock);
 
index 08b8bb9..7c39623 100644 (file)
@@ -726,7 +726,7 @@ int nodemap_idx_idmap_add(const struct lu_nodemap *nodemap,
        ENTRY;
 
        if (!nodemap_mgs()) {
-               CERROR("cannot add nodemap config to non-existing MGS.\n");
+               CERROR("cannot add idmap to non-existing MGS.\n");
                return -EINVAL;
        }
 
@@ -753,7 +753,7 @@ int nodemap_idx_idmap_del(const struct lu_nodemap *nodemap,
        ENTRY;
 
        if (!nodemap_mgs()) {
-               CERROR("cannot add nodemap config to non-existing MGS.\n");
+               CERROR("cannot del idmap from non-existing MGS.\n");
                return -EINVAL;
        }
 
index 1571353..3b83ea1 100755 (executable)
@@ -6792,6 +6792,8 @@ test_72() {
        local nids=1.1.1.[1-100]@tcp
        local startnid=1.1.1.1@tcp
        local endnid=1.1.1.100@tcp
+       local clid=500
+       local fsid=1000
        local val
 
        (( OST1_VERSION >= $(version_code 2.15.64) )) ||
@@ -6833,6 +6835,29 @@ test_72() {
                error "dynamic nodemap wrong end nid range $val"
        fi
 
+       do_facet ost1 $LCTL nodemap_add_idmap --name $nm --idtype uid \
+               --idmap $clid:$fsid ||
+                       error "dynamic add_idmap on server failed"
+       val=$(do_facet ost1 $LCTL get_param nodemap.$nm.idmap |
+               awk 'BEGIN{RS=", "} $1=="client_id:"{print $2 ; exit}')
+       if [[ "x$val" != "x$clid" ]]; then
+               error "dynamic nodemap wrong client id $val"
+       fi
+       val=$(do_facet ost1 $LCTL get_param nodemap.$nm.idmap |
+               awk 'BEGIN{RS=", "} $1=="fs_id:"{print $2 ; exit}')
+       if [[ "x$val" != "x$fsid" ]]; then
+               error "dynamic nodemap wrong fs id $val"
+       fi
+
+       do_facet ost1 $LCTL nodemap_del_idmap --name $nm --idtype uid \
+               --idmap $clid:$fsid ||
+                       error "dynamic del_idmap on server failed"
+       val=$(do_facet ost1 $LCTL get_param nodemap.$nm.idmap |
+               awk 'BEGIN{RS=", "} $1=="client_id:"{print $2 ; exit}')
+       if [[ "x$val" != "x" ]]; then
+               error "idmap should be empty, got $val"
+       fi
+
        do_facet ost1 $LCTL nodemap_del_range --name $nm --range $nids ||
                error "dynamic del_range on server failed"
        val=$(do_facet ost1 $LCTL get_param nodemap.$nm.ranges |
@@ -6852,6 +6877,12 @@ test_72() {
                        error "add_range $mgsnm on server should fail"
        do_facet ost1 $LCTL nodemap_del_range --name $mgsnm --range $mgsnids &&
                error "del_range $mgsnm on server should fail"
+       do_facet ost1 $LCTL nodemap_add_idmap --name $mgsnm --idtype gid \
+               --idmap $mgsclid:$mgsfsid &&
+                       error "add_idmap $mgsnm on server should fail"
+       do_facet ost1 $LCTL nodemap_del_idmap --name $mgsnm --idtype uid \
+               --idmap $mgsclid:$mgsfsid &&
+                       error "del_idmap $mgsnm on server should fail"
        do_facet ost1 $LCTL nodemap_del $mgsnm &&
                error "nodemap del $mgsnm on server should fail"
        do_facet ost1 $LCTL get_param -R 'nodemap.*'
index 867ee55..9e6c43f 100644 (file)
@@ -524,9 +524,11 @@ command_t cmdlist[] = {
         "delete an offset for UID/GID/PROJID mappings\n"
         "usage: nodemap_del_offset --name NODEMAP_NAME --offset OFFSET\n"},
        {"nodemap_add_idmap", jt_nodemap_add_idmap, 0,
-        "add a UID or GID mapping to a nodemap"},
+        "add a UID or GID mapping to a nodemap\n"
+        "usage: nodemap_add_idmap --name NODEMAP_NAME --idtype ID_TYPE --idmap CLIENTID:FSID"},
        {"nodemap_del_idmap", jt_nodemap_del_idmap, 0,
-        "delete a UID or GID mapping from a nodemap"},
+        "delete a UID or GID mapping from a nodemap\n"
+        "usage: nodemap_del_idmap --name NODEMAP_NAME --idtype ID_TYPE --idmap CLIENTID:FSID"},
        {"nodemap_set_fileset", jt_nodemap_set_fileset, 0,
         "set a fileset on a nodemap\n"
         "usage: nodemap_set_fileset <fileset>"},
index d8fe19e..d7cfa0a 100644 (file)
@@ -4731,39 +4731,52 @@ int jt_nodemap_del_offset(int argc, char **argv)
 
 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;
+       enum lcfg_command_type cmd = 0;
+       char *nodemap_name = NULL;
+       char *idtype = NULL;
+       char *idmap = NULL;
+       int c, rc = 0;
 
        static struct option long_opts[] = {
+       { .val = 'h',   .name = "help",         .has_arg = no_argument },
        { .val = 'i',   .name = "idtype",       .has_arg = required_argument },
        { .val = 'm',   .name = "idmap",        .has_arg = required_argument },
        { .val = 'n',   .name = "name",         .has_arg = required_argument },
        { .name = NULL } };
 
-       while ((c = getopt_long(argc, argv, "n:m:i:",
+       while ((c = getopt_long(argc, argv, "hi:m:n:",
                                long_opts, NULL)) != -1) {
                switch (c) {
-               case 'n':
-                       nodemap_name = optarg;
+               case 'i':
+                       idtype = optarg;
                        break;
                case 'm':
                        idmap = optarg;
                        break;
-               case 'i':
-                       idtype = optarg;
+               case 'n':
+                       nodemap_name = optarg;
                        break;
+               case 'h':
+               default:
+                       goto add_idmap_usage;
                }
        }
 
-       if (!nodemap_name || !idmap || !idtype) {
+       if (!nodemap_name) {
+               fprintf(stderr, "nodemap_add_idmap: missing nodemap name\n");
+add_idmap_usage:
                fprintf(stderr,
-                       "usage: %s --name <name> --idtype [uid | gid | projid] --idmap <client id>:<filesystem id>\n",
+                       "usage: %s --name NODEMAP_NAME --idtype ID_TYPE --idmap CLIENTID:FSID\n",
                        argv[0]);
-               return -1;
+               return -EINVAL;
+       }
+       if (!idtype) {
+               fprintf(stderr, "nodemap_add_idmap: missing ID type\n");
+               goto add_idmap_usage;
+       }
+       if (!idmap) {
+               fprintf(stderr, "nodemap_add_idmap: missing ID map\n");
+               goto add_idmap_usage;
        }
 
        if (strcmp("uid", idtype) == 0) {
@@ -4774,9 +4787,8 @@ int jt_nodemap_add_idmap(int argc, char **argv)
                cmd = LCFG_NODEMAP_ADD_PROJIDMAP;
        } else {
                fprintf(stderr,
-                       "usage: %s --name <name> --idtype [uid | gid | projid] --idmap <client id>:<filesystem id>\n",
-                       argv[0]);
-               return -1;
+                       "nodemap_add_idmap: incorrect ID type, must be one of uid, gid, projid.\n");
+               goto add_idmap_usage;
        }
 
        rc = nodemap_cmd(cmd, false, NULL, 0,
@@ -4792,39 +4804,52 @@ int jt_nodemap_add_idmap(int argc, char **argv)
 
 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;
+       enum lcfg_command_type cmd = 0;
+       char *nodemap_name = NULL;
+       char *idtype = NULL;
+       char *idmap = NULL;
+       int c, rc = 0;
 
        static struct option long_opts[] = {
+       { .val = 'h',   .name = "help",         .has_arg = no_argument },
        { .val = 'i',   .name = "idtype",       .has_arg = required_argument },
        { .val = 'm',   .name = "idmap",        .has_arg = required_argument },
        { .val = 'n',   .name = "name",         .has_arg = required_argument },
        { .name = NULL } };
 
-       while ((c = getopt_long(argc, argv, "n:m:i:",
+       while ((c = getopt_long(argc, argv, "hi:m:n:",
                                long_opts, NULL)) != -1) {
                switch (c) {
-               case 'n':
-                       nodemap_name = optarg;
+               case 'i':
+                       idtype = optarg;
                        break;
                case 'm':
                        idmap = optarg;
                        break;
-               case 'i':
-                       idtype = optarg;
+               case 'n':
+                       nodemap_name = optarg;
                        break;
+               case 'h':
+               default:
+                       goto del_idmap_usage;
                }
        }
 
-       if (!nodemap_name || !idmap || !idtype) {
+       if (!nodemap_name) {
+               fprintf(stderr, "nodemap_del_idmap: missing nodemap name\n");
+del_idmap_usage:
                fprintf(stderr,
-                       "usage: %s --name <name> --idtype [uid | gid | projid] --idmap <client id>:<filesystem id>\n",
+                       "usage: %s --name NODEMAP_NAME --idtype ID_TYPE --idmap CLIENTID:FSID\n",
                        argv[0]);
-               return -1;
+               return -EINVAL;
+       }
+       if (!idtype) {
+               fprintf(stderr, "nodemap_del_idmap: missing ID type\n");
+               goto del_idmap_usage;
+       }
+       if (!idmap) {
+               fprintf(stderr, "nodemap_del_idmap: missing ID map\n");
+               goto del_idmap_usage;
        }
 
        if (strcmp("uid", idtype) == 0) {
@@ -4835,9 +4860,8 @@ int jt_nodemap_del_idmap(int argc, char **argv)
                cmd = LCFG_NODEMAP_DEL_PROJIDMAP;
        } else {
                fprintf(stderr,
-                       "usage: %s --name <name> --idtype [uid | gid | projid] --idmap <client id>:<filesystem id>\n",
-                       argv[0]);
-               return -1;
+                       "nodemap_del_idmap: incorrect ID type, must be one of uid, gid, projid.\n");
+               goto del_idmap_usage;
        }
 
        rc = nodemap_cmd(cmd, false, NULL, 0,