Whamcloud - gitweb
LU-9680 lnet: add NLM_F_DUMP_FILTERED support 04/53004/15
authorJames Simmons <jsimmons@infradead.org>
Wed, 28 Feb 2024 19:34:38 +0000 (14:34 -0500)
committerOleg Drokin <green@whamcloud.com>
Wed, 13 Mar 2024 03:21:32 +0000 (03:21 +0000)
In addition to different API levels for the netlink packets we
can also filter the data sent back when user land sends the
NLM_F_DUMP_FILTERED. Support this across the various netlink
dumpit functions.

This work is needed for the proper support for lnetctl export
command. Update the export to work with the Netlink API. This
results in proper IPv6 support for the export command.

Test-Parameters: trivial testlist=sanity-lnet
Change-Id: I0e8993b1f9a08199f282965601781aa6fd0e4844
Signed-off-by: James Simmons <jsimmons@infradead.org>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53004
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Frank Sehr <fsehr@whamcloud.com>
Reviewed-by: Chris Horn <chris.horn@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
libcfs/include/libcfs/linux/linux-net.h
lnet/lnet/api-ni.c
lnet/utils/lnetctl.c
lustre/tests/sanity-lnet.sh

index b13a1e6..a2ce21c 100644 (file)
 } while (0)
 #endif
 
+#ifndef NLM_F_DUMP_FILTERED
+#define NLM_F_DUMP_FILTERED   0x20    /* Dump was filtered as requested */
+#endif
+
 #ifndef HAVE_NLA_STRDUP
 char *nla_strdup(const struct nlattr *nla, gfp_t flags);
 #endif /* !HAVE_NLA_STRDUP */
index de2c556..b8c2edc 100644 (file)
@@ -5437,6 +5437,26 @@ report_err:
        return rc;
 }
 
+static const struct ln_key_list net_update_props_list = {
+       .lkl_maxattr                    = LNET_NET_ATTR_MAX,
+       .lkl_list                       = {
+               [LNET_NET_ATTR_HDR]             = {
+                       .lkp_value              = "",
+                       .lkp_key_format         = LNKF_SEQUENCE | LNKF_MAPPING,
+                       .lkp_data_type          = NLA_NUL_STRING,
+               },
+               [LNET_NET_ATTR_TYPE]            = {
+                       .lkp_value              = "net type",
+                       .lkp_data_type          = NLA_STRING
+               },
+               [LNET_NET_ATTR_LOCAL]           = {
+                       .lkp_value              = "local NI(s)",
+                       .lkp_key_format         = LNKF_SEQUENCE | LNKF_MAPPING,
+                       .lkp_data_type          = NLA_NESTED
+               },
+       },
+};
+
 static int lnet_net_show_dump(struct sk_buff *msg,
                              struct netlink_callback *cb)
 {
@@ -5446,7 +5466,7 @@ static int lnet_net_show_dump(struct sk_buff *msg,
 #endif
        struct genlmsghdr *gnlh = nlmsg_data(cb->nlh);
        int portid = NETLINK_CB(cb->skb).portid;
-       bool found = false, started = true;
+       bool found = false, started = false;
        const struct lnet_lnd *lnd = NULL;
        int idx = nlist->lngl_idx, rc = 0;
        int seq = cb->nlh->nlmsg_seq;
@@ -5467,6 +5487,10 @@ static int lnet_net_show_dump(struct sk_buff *msg,
                    nlist->lngl_net_id != net->net_id)
                        continue;
 
+               if (cb->nlh->nlmsg_flags & NLM_F_DUMP_FILTERED &&
+                   LNET_NETTYP(net->net_id) == LOLND)
+                       continue;
+
                if (gnlh->version && LNET_NETTYP(net->net_id) != LOLND) {
                        if (!net->net_lnd) {
                                NL_SET_ERR_MSG(extack,
@@ -5502,9 +5526,10 @@ static int lnet_net_show_dump(struct sk_buff *msg,
 
                        if (lnd) {
                                all[ARRAY_SIZE(all) - 2] = lnd->lnd_keys;
-                               if (idx)
+                               if (idx) {
+                                       all[0] = &net_update_props_list;
                                        flags |= NLM_F_REPLACE;
-                               started = true;
+                               }
                        }
 
                        rc = lnet_genl_send_scalar_list(msg, portid, seq,
@@ -5514,6 +5539,7 @@ static int lnet_net_show_dump(struct sk_buff *msg,
                                NL_SET_ERR_MSG(extack, "failed to send key table");
                                GOTO(net_unlock, rc);
                        }
+                       started = true;
                }
 
                hdr = genlmsg_put(msg, portid, seq, &lnet_family,
@@ -5541,13 +5567,15 @@ static int lnet_net_show_dump(struct sk_buff *msg,
                        ni_attr = nla_nest_start(msg, dev++);
                        found = true;
                        lnet_ni_lock(ni);
-                       nla_put_string(msg, LNET_NET_LOCAL_NI_ATTR_NID,
-                                      libcfs_nidstr(&ni->ni_nid));
-                       if (!nid_is_lo0(&ni->ni_nid) &&
-                           lnet_ni_get_status_locked(ni) != LNET_NI_STATUS_UP)
-                               status = "down";
-                       nla_put_string(msg, LNET_NET_LOCAL_NI_ATTR_STATUS,
-                                      status);
+                       if (!(cb->nlh->nlmsg_flags & NLM_F_DUMP_FILTERED)) {
+                               nla_put_string(msg, LNET_NET_LOCAL_NI_ATTR_NID,
+                                              libcfs_nidstr(&ni->ni_nid));
+                               if (!nid_is_lo0(&ni->ni_nid) &&
+                                   lnet_ni_get_status_locked(ni) != LNET_NI_STATUS_UP)
+                                       status = "down";
+                               nla_put_string(msg, LNET_NET_LOCAL_NI_ATTR_STATUS,
+                                              status);
+                       }
 
                        if (!nid_is_lo0(&ni->ni_nid) && ni->ni_interface) {
                                struct nlattr *intf_nest, *intf_attr;
@@ -5575,6 +5603,11 @@ static int lnet_net_show_dump(struct sk_buff *msg,
                                struct nlattr *tun_attr, *ni_tun;
                                int j;
 
+                               if (cb->nlh->nlmsg_flags & NLM_F_DUMP_FILTERED) {
+                                       lnet_ni_unlock(ni);
+                                       goto skip_msg_stats;
+                               }
+
                                stats.iel_send_count = lnet_sum_stats(&ni->ni_stats,
                                                                      LNET_STATS_TYPE_SEND);
                                stats.iel_recv_count = lnet_sum_stats(&ni->ni_stats,
@@ -5727,7 +5760,9 @@ skip_msg_stats:
                                        nla_nest_end(msg, lnd_tun_attr);
                                }
 
-                               nla_put_s32(msg, LNET_NET_LOCAL_NI_DEV_CPT, ni->ni_dev_cpt);
+                               if (!(cb->nlh->nlmsg_flags & NLM_F_DUMP_FILTERED))
+                                       nla_put_s32(msg, LNET_NET_LOCAL_NI_DEV_CPT,
+                                                   ni->ni_dev_cpt);
 
                                /* Report cpts. We could send this as a nested list
                                 * of integers but older versions of the tools
@@ -6959,12 +6994,14 @@ static int lnet_route_show_dump(struct sk_buff *msg,
                        nla_put_u32(msg, LNET_ROUTE_ATTR_HEALTH_SENSITIVITY,
                                    prop->lrp_sensitivity);
 
-                       nla_put_string(msg, LNET_ROUTE_ATTR_STATE,
-                                      prop->lrp_flags & LNET_RT_ALIVE ?
-                                      "up" : "down");
-                       nla_put_string(msg, LNET_ROUTE_ATTR_TYPE,
-                                      prop->lrp_flags & LNET_RT_MULTI_HOP ?
-                                      "multi-hop" : "single-hop");
+                       if (!(cb->nlh->nlmsg_flags & NLM_F_DUMP_FILTERED)) {
+                               nla_put_string(msg, LNET_ROUTE_ATTR_STATE,
+                                              prop->lrp_flags & LNET_RT_ALIVE ?
+                                              "up" : "down");
+                               nla_put_string(msg, LNET_ROUTE_ATTR_TYPE,
+                                              prop->lrp_flags & LNET_RT_MULTI_HOP ?
+                                              "multi-hop" : "single-hop");
+                       }
                }
                genlmsg_end(msg, hdr);
        }
@@ -7419,6 +7456,9 @@ static int lnet_peer_ni_show_dump(struct sk_buff *msg,
                                }
                        }
 
+                       if (cb->nlh->nlmsg_flags & NLM_F_DUMP_FILTERED)
+                               goto skip_state;
+
                        if (lnet_isrouter(lpni) ||
                            lnet_peer_aliveness_enabled(lpni)) {
                                nla_put_string(msg, LNET_PEER_NI_LIST_ATTR_STATE,
@@ -7428,7 +7468,7 @@ static int lnet_peer_ni_show_dump(struct sk_buff *msg,
                                nla_put_string(msg, LNET_PEER_NI_LIST_ATTR_STATE,
                                               "NA");
                        }
-
+skip_state:
                        if (gnlh->version) {
                                struct lnet_ioctl_element_msg_stats lpni_msg_stats;
                                struct nlattr *send_stats_list, *send_stats;
index 47143d0..8851c1c 100644 (file)
 #define LNET_CONFIGURE         true
 #define LNET_UNCONFIGURE       false
 
+#ifndef NLM_F_DUMP_FILTERED
+#define NLM_F_DUMP_FILTERED    0x20
+#endif
+
 static int jt_config_lnet(int argc, char **argv);
 static int jt_unconfig_lnet(int argc, char **argv);
 static int jt_add_route(int argc, char **argv);
@@ -3909,22 +3913,24 @@ static int jt_export(int argc, char **argv)
 {
        struct cYAML *show_rc = NULL;
        struct cYAML *err_rc = NULL;
+       int flags = NLM_F_DUMP;
        int rc;
        FILE *f = NULL;
        int opt;
        bool backup = false;
        char *file = NULL;
-
        const char *const short_options = "bh";
        static const struct option long_options[] = {
                { .name = "backup", .has_arg = no_argument, .val = 'b' },
                { .name = "help", .has_arg = no_argument, .val = 'h' },
-               { .name = NULL } };
+               { .name = NULL }
+       };
 
        while ((opt = getopt_long(argc, argv, short_options,
                                   long_options, NULL)) != -1) {
                switch (opt) {
                case 'b':
+                       flags |= NLM_F_DUMP_FILTERED;
                        backup = true;
                        break;
                case 'h':
@@ -3949,6 +3955,36 @@ static int jt_export(int argc, char **argv)
                        return -1;
        }
 
+       rc = yaml_lnet_config_ni(NULL, NULL, NULL, NULL, -1, NULL,
+                                flags & NLM_F_DUMP_FILTERED ? 1 : 2,
+                                flags);
+       if (rc < 0) {
+               if (rc == -EOPNOTSUPP)
+                       goto old_api;
+       }
+
+       rc = yaml_lnet_route(NULL, NULL, -1, -1, -1, LNET_GENL_VERSION, flags);
+       if (rc < 0) {
+               if (rc == -EOPNOTSUPP)
+                       goto old_api;
+       }
+
+       rc = lustre_lnet_show_routing(-1, &show_rc, &err_rc, backup);
+       if (rc != LUSTRE_CFG_RC_NO_ERR) {
+               cYAML_print_tree2file(stderr, err_rc);
+               cYAML_free_tree(err_rc);
+               err_rc = NULL;
+       }
+
+       rc = yaml_lnet_peer(NULL, NULL, false, -1, false, false,
+                           flags & NLM_F_DUMP_FILTERED ? 0 : 3, flags);
+       if (rc < 0) {
+               if (rc == -EOPNOTSUPP)
+                       goto old_api;
+       }
+       goto show_others;
+
+old_api:
        rc = lustre_lnet_show_net(NULL, 2, -1, &show_rc, &err_rc, backup);
        if (rc != LUSTRE_CFG_RC_NO_ERR) {
                cYAML_print_tree2file(stderr, err_rc);
@@ -3977,7 +4013,7 @@ static int jt_export(int argc, char **argv)
                cYAML_free_tree(err_rc);
                err_rc = NULL;
        }
-
+show_others:
        rc = lustre_lnet_show_numa_range(-1, &show_rc, &err_rc);
        if (rc != LUSTRE_CFG_RC_NO_ERR) {
                cYAML_print_tree2file(stderr, err_rc);
index 9c2c14a..78cc861 100755 (executable)
@@ -192,8 +192,8 @@ validate_peer_nids() {
        # The primary nid also shows up in the list of secondary nids
        local expect_s="$(($num_peers + $(($nids_per_peer*$num_peers))))"
 
-       local actual_p=$(grep -c -- '- primary nid:' $TMP/sanity-lnet-$testnum-actual.yaml)
-       local actual_s=$(grep -c -- '- nid:' $TMP/sanity-lnet-$testnum-actual.yaml)
+       local actual_p=$(awk '/-\s+primary nid:/{print $NF}' $TMP/sanity-lnet-$testnum-actual.yaml | wc -l)
+       local actual_s=$(awk '/-\s+nid:/{print $NF}' $TMP/sanity-lnet-$testnum-actual.yaml | wc -l)
        if [[ $expect_p -ne $actual_p ]]; then
                compare_yaml_files
                error "Expected $expect_p but found $actual_p primary nids"