From fb3459589e98169b1af2858abc70fafdf59c313d Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Wed, 20 Mar 2024 16:50:54 +0100 Subject: [PATCH] LU-17431 nodemap: allow handling an id map for a dynamic nm 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 Change-Id: I055cf1d67b72a6bca5140814c4346ac578f2f31d Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54509 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger Reviewed-by: Marc Vef --- lustre/ptlrpc/nodemap_handler.c | 8 ++-- lustre/ptlrpc/nodemap_storage.c | 4 +- lustre/tests/sanity-sec.sh | 31 ++++++++++++++ lustre/utils/lctl.c | 6 ++- lustre/utils/obd.c | 92 ++++++++++++++++++++++++++--------------- 5 files changed, 100 insertions(+), 41 deletions(-) diff --git a/lustre/ptlrpc/nodemap_handler.c b/lustre/ptlrpc/nodemap_handler.c index 2238a57..34995b6 100644 --- a/lustre/ptlrpc/nodemap_handler.c +++ b/lustre/ptlrpc/nodemap_handler.c @@ -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); diff --git a/lustre/ptlrpc/nodemap_storage.c b/lustre/ptlrpc/nodemap_storage.c index 08b8bb9..7c39623 100644 --- a/lustre/ptlrpc/nodemap_storage.c +++ b/lustre/ptlrpc/nodemap_storage.c @@ -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; } diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index 1571353..3b83ea1 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -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.*' diff --git a/lustre/utils/lctl.c b/lustre/utils/lctl.c index 867ee55..9e6c43f 100644 --- a/lustre/utils/lctl.c +++ b/lustre/utils/lctl.c @@ -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 "}, diff --git a/lustre/utils/obd.c b/lustre/utils/obd.c index d8fe19e..d7cfa0a 100644 --- a/lustre/utils/obd.c +++ b/lustre/utils/obd.c @@ -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 --idtype [uid | gid | projid] --idmap :\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 --idtype [uid | gid | projid] --idmap :\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 --idtype [uid | gid | projid] --idmap :\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 --idtype [uid | gid | projid] --idmap :\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, -- 1.8.3.1