Whamcloud - gitweb
LU-13621 lnet: utility to print cpt number
authorAmir Shehata <ashehata@whamcloud.com>
Fri, 19 Jun 2020 23:31:36 +0000 (16:31 -0700)
committerAndreas Dilger <adilger@whamcloud.com>
Wed, 9 Mar 2022 17:14:47 +0000 (17:14 +0000)
Added a command to lnetctl to print the cpt of the NID.
lnetctl cpt-of-nid --nid <nid> --ncpt <number of cpts>
ex:
lnetctl cpt-of-nid --nid 192.28.12.35@tcp9 --ncpt 7
This will return what cpt the NID will hash to within the 0-6 range.
If the NI is bound to specific set of CPTs, then the ncpts refers
to the number of CPTs the NI is bound to. The cpt value returned
will be an index into the list of bound CPTs.

For example if an NI is bound to [0,4,5,7], then the ncpt should be
4. And the returned value will be an index in the array:
ex:
lnetctl cpt-of-nid --nid 192.28.12.35@tcp9 --ncpt 4
cpt:
    value: 1
therefore, the actual CPT the NID will be bound to is 4.

Lustre-change: https://review.whamcloud.com/39113
Lustre-commit: df6f17ee97ac47c949c1963ff8d57fb2d4becd06

Test-parameters: trivial testlist=sanity-lnet

Signed-off-by: Amir Shehata <ashehata@whamcloud.com>
Change-Id: I3cb562842448bfb663c2d41007be65299a919300
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/46397
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
lnet/utils/lnetconfig/liblnetconfig.c
lnet/utils/lnetconfig/liblnetconfig.h
lnet/utils/lnetctl.c

index aa667c2..46d2d27 100644 (file)
@@ -44,6 +44,7 @@
 #include <sys/ioctl.h>
 #include <net/if.h>
 #include <libcfs/util/ioctl.h>
+#include <libcfs/util/hash.h>
 #include <linux/lnet/lnetctl.h>
 #include "liblnd.h"
 #include <sys/types.h>
@@ -3616,6 +3617,52 @@ out:
        return rc;
 }
 
+unsigned int
+lnet_nid_cpt_hash(lnet_nid_t nid, long int number)
+{
+       __u64           key = nid;
+       unsigned int    val;
+       int cpt_bits = 0;
+
+       if (number == 1)
+               return 0;
+
+       while ((1 << cpt_bits) < number)
+               cpt_bits++;
+
+       val = hash_long(key, cpt_bits);
+       /* NB: LNET_CP_NUMBER doesn't have to be PO2 */
+       if (val < number)
+               return val;
+
+       return (unsigned int)(key + val + (val >> 1)) % number;
+}
+
+int lustre_lnet_calc_cpt_of_nid(char *nidc, long int ncpts)
+{
+       int rc = LUSTRE_CFG_RC_BAD_PARAM;
+       lnet_nid_t nid;
+
+       if (!nidc) {
+               fprintf(stderr, "error:\n    msg: \"no NID provided\"\n");
+               return rc;
+       }
+
+       if (ncpts < 0) {
+               fprintf(stderr, "error:\n    msg: \"number of CPTs not provided\"\n");
+               return rc;
+       }
+
+       nid = libcfs_str2nid(nidc);
+       if (nid == LNET_NID_ANY) {
+               fprintf(stderr, "error:\n    msg: \"bad NID provided %s\"\n",
+                       nidc);
+               return rc;
+       }
+
+       return (int)lnet_nid_cpt_hash(nid, ncpts);
+}
+
 int show_recovery_queue(enum lnet_health_type type, char *name, int seq_no,
                        struct cYAML **show_rc, struct cYAML **err_rc)
 {
index d39ccaf..dee59b5 100644 (file)
@@ -464,6 +464,12 @@ int lustre_lnet_calc_service_id(__u64 *service_id);
 int lustre_lnet_setup_mrrouting(struct cYAML **err_rc);
 
 /*
+ * lustre_lnet_calc_cpt_of_nid
+ *     Return the cpt number of the NID provided
+ */
+int lustre_lnet_calc_cpt_of_nid(char *nidc, long int ncpts);
+
+/*
  * lustre_lnet_config_discovery
  *   Enable or disable peer discovery. Peer discovery is enabled by default.
  *
index 72dc7aa..73fb386 100644 (file)
@@ -86,6 +86,7 @@ static int jt_calc_service_id(int argc, char **argv);
 static int jt_set_response_tracking(int argc, char **argv);
 static int jt_set_recovery_limit(int argc, char **argv);
 static int jt_setup_mrrouting(int argc, char **argv);
+static int jt_calc_cpt_of_nid(int argc, char **argv);
 
 command_t cmd_list[] = {
        {"lnet", jt_lnet, 0, "lnet {configure | unconfigure} [--all]"},
@@ -109,6 +110,9 @@ command_t cmd_list[] = {
        {"service-id", jt_calc_service_id, 0, "Calculate IB Lustre service ID\n"},
        {"setup-mrrouting", jt_setup_mrrouting, 0,
         "setup linux routing tables\n"},
+       {"cpt-of-nid", jt_calc_cpt_of_nid, 0, "Calculate the CPT associated with NID\n"
+        "\t--nid: NID to calculate the CPT of\n"
+        "\t--ncpt: Number of CPTs to consider in the calculation\n"},
        {"help", Parser_help, 0, "help"},
        {"exit", Parser_quit, 0, "quit"},
        {"quit", Parser_quit, 0, "quit"},
@@ -265,22 +269,18 @@ command_t peer_cmds[] = {
        { 0, 0, 0, NULL }
 };
 
-static int jt_calc_service_id(int argc, char **argv)
+static int parse_long(const char *number, long int *value)
 {
-       int rc;
-       __u64 service_id;
+       char *end;
 
-       rc = lustre_lnet_calc_service_id(&service_id);
-       if (rc != LUSTRE_CFG_RC_NO_ERR)
-               return rc;
+       if (!number)
+               return -1;
 
-       /*
-        * cYAML currently doesn't support printing hex values.
-        * Therefore just print it locally here
-        */
-       printf("service id:\n    value: 0x%jx\n", (uintmax_t)service_id);
+       *value = strtol(number,  &end, 0);
+       if (end != NULL && *end != 0)
+               return -1;
 
-       return rc;
+       return 0;
 }
 
 static int jt_setup_mrrouting(int argc, char **argv)
@@ -316,20 +316,6 @@ static inline void print_help(const command_t cmds[], const char *cmd_type,
        }
 }
 
-static int parse_long(const char *number, long int *value)
-{
-       char *end;
-
-       if (!number)
-               return -1;
-
-       *value = strtol(number,  &end, 0);
-       if (end != NULL && *end != 0)
-               return -1;
-
-       return 0;
-}
-
 static int check_cmd(const command_t *cmd_list, const char *cmd,
                     const char *sub_cmd, const int min_args,
                     int argc, char **argv)
@@ -401,6 +387,73 @@ static int jt_set_response_tracking(int argc, char **argv)
        return rc;
 }
 
+static int jt_calc_service_id(int argc, char **argv)
+{
+       int rc;
+       __u64 service_id;
+
+       rc = lustre_lnet_calc_service_id(&service_id);
+       if (rc != LUSTRE_CFG_RC_NO_ERR)
+               return rc;
+
+       /* cYAML currently doesn't support printing hex values.
+        * Therefore just print it locally here
+        */
+       printf("service_id:\n    value: 0x%llx\n",
+              (unsigned long long)(service_id));
+
+       return rc;
+}
+
+static int jt_calc_cpt_of_nid(int argc, char **argv)
+{
+       int rc, opt;
+       int cpt;
+       long int ncpts = -1;
+       char *nid = NULL;
+       struct cYAML *err_rc = NULL;
+       const char *const short_options = "n:c:h";
+       static const struct option long_options[] = {
+       { .name = "nid",       .has_arg = required_argument, .val = 'n' },
+       { .name = "ncpt",     .has_arg = required_argument, .val = 'c' },
+       { .name = NULL } };
+
+       rc = check_cmd(cmd_list, "", "cpt-of-nid", 0, argc, argv);
+       if (rc)
+               return rc;
+
+       while ((opt = getopt_long(argc, argv, short_options,
+                                  long_options, NULL)) != -1) {
+               switch (opt) {
+               case 'n':
+                       nid = optarg;
+                       break;
+               case 'c':
+                       rc = parse_long(optarg, &ncpts);
+                       if (rc != 0) {
+                               cYAML_build_error(-1, -1, "cpt", "get",
+                                               "cannot parse input", &err_rc);
+                               cYAML_print_tree2file(stderr, err_rc);
+                               cYAML_free_tree(err_rc);
+                               return -1;
+                       }
+                       break;
+               case '?':
+                       print_help(cmd_list, "", "cpt-of-nid");
+               default:
+                       return 0;
+               }
+       }
+
+       cpt = lustre_lnet_calc_cpt_of_nid(nid, ncpts);
+       if (cpt < 0)
+               return -1;
+
+       printf("cpt:\n    value: %d\n", cpt);
+
+       return 0;
+}
+
 static int jt_set_recovery_limit(int argc, char **argv)
 {
        long int value;