Whamcloud - gitweb
LU-13621 lnet: utility to print cpt number 13/39113/9
authorAmir Shehata <ashehata@whamcloud.com>
Fri, 19 Jun 2020 23:31:36 +0000 (16:31 -0700)
committerOleg Drokin <green@whamcloud.com>
Mon, 31 Jan 2022 01:25:25 +0000 (01:25 +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.

Test-parameters: trivial testlist=sanity-lnet

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

index 0b8b110..8db3f4d 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>
@@ -3790,6 +3791,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 dae9268..05d186f 100644 (file)
@@ -539,6 +539,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 6c76812..51dfab6 100644 (file)
@@ -91,6 +91,7 @@ static int jt_set_response_tracking(int argc, char **argv);
 static int jt_set_recovery_limit(int argc, char **argv);
 static int jt_udsp(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]"},
@@ -115,6 +116,9 @@ command_t cmd_list[] = {
        {"udsp", jt_udsp, 0, "udsp {add | del | help}"},
        {"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"},
@@ -287,22 +291,18 @@ command_t udsp_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)
@@ -338,20 +338,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)
@@ -423,6 +409,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;