#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>
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)
{
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]"},
{"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"},
{ 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)
}
}
-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)
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;