static char *convert_hostnames(char *s1) { char *converted, *s2 = 0, *c; char sep; int left = MAXNIDSTR; lnet_nid_t nid; converted = malloc(left); if (converted == NULL) { fprintf(stderr, "out of memory: needed %d bytes\n", MAXNIDSTR); return NULL; } c = converted; while ((left > 0) && (*s1 != '/')) { s2 = strpbrk(s1, ",:"); if (!s2) goto out_free; sep = *s2; *s2 = '\0'; nid = libcfs_str2nid(s1); *s2 = sep; /* back to original string */ if (nid == LNET_NID_ANY) goto out_free; c += snprintf(c, left, "%s%c", libcfs_nid2str(nid), sep); left = converted + MAXNIDSTR - c; s1 = s2 + 1; } snprintf(c, left, "%s", s1); return converted; out_free: fprintf(stderr, "%s: Can't parse NID '%s'\n", progname, s1); free(converted); return NULL; }
int sli_rmi_setmds(const char *name) { struct slashrpc_cservice *csvc; struct sl_resource *res; // struct sl_resm *old; lnet_nid_t nid; /* XXX kill any old MDS and purge any bmap updates being held */ // slconnthr_unwatch(rmi_resm->resm_csvc); // old = rmi_resm; // sl_csvc_disable(old->resm_csvc); nid = libcfs_str2nid(name); if (nid == LNET_NID_ANY) { res = libsl_str2res(name); if (res == NULL) return (SLERR_RES_UNKNOWN); rmi_resm = psc_dynarray_getpos(&res->res_members, 0); } else rmi_resm = libsl_nid2resm(nid); if (sli_rmi_getcsvc(&csvc)) psclog_errorx("error connecting to MDS"); else { slconnthr_watch(sliconnthr, csvc, CSVCF_PING, NULL, NULL); sl_csvc_decref(csvc); } return (0); }
int libcfs_str2anynid(lnet_nid_t *nidp, const char *str) { if (!strcmp(str, "*")) { *nidp = LNET_NID_ANY; return 1; } *nidp = libcfs_str2nid(str); return *nidp != LNET_NID_ANY; }
int jt_lcfg_add_uuid(int argc, char **argv) { lnet_nid_t nid; if (argc != 3) { return CMD_HELP; } nid = libcfs_str2nid(argv[2]); if (nid == LNET_NID_ANY) { fprintf (stderr, "Can't parse NID %s\n", argv[2]); return (-1); } return do_add_uuid(argv[0], argv[1], nid); }
static char *convert_hostnames(char *s1) { char *converted, *s2 = 0, *c, *end, sep; int left = MAXNIDSTR; lnet_nid_t nid; converted = malloc(left); if (converted == NULL) { return NULL; } end = s1 + strlen(s1); c = converted; while ((left > 0) && (s1 < end)) { s2 = strpbrk(s1, ",:"); if (!s2) s2 = end; sep = *s2; *s2 = '\0'; nid = libcfs_str2nid(s1); *s2 = sep; if (nid == LNET_NID_ANY) { fprintf(stderr, "%s: Cannot resolve hostname '%s'.\n", progname, s1); free(converted); return NULL; } if (strncmp(libcfs_nid2str(nid), "127.0.0.1", strlen("127.0.0.1")) == 0) { fprintf(stderr, "%s: The NID '%s' resolves to the " "loopback address '%s'. Lustre requires a " "non-loopback address.\n", progname, s1, libcfs_nid2str(nid)); free(converted); return NULL; } c += snprintf(c, left, "%s%c", libcfs_nid2str(nid), sep); left = converted + MAXNIDSTR - c; s1 = s2 + 1; } return converted; }
int lustre_lnet_config_route(char *nw, char *gw, int hops, int prio, int seq_no, struct cYAML **err_rc) { struct lnet_ioctl_config_data data; lnet_nid_t gateway_nid; int rc = LUSTRE_CFG_RC_NO_ERR; __u32 net = LNET_NIDNET(LNET_NID_ANY); char err_str[LNET_MAX_STR_LEN]; snprintf(err_str, sizeof(err_str), "\"Success\""); if (nw == NULL || gw == NULL) { snprintf(err_str, sizeof(err_str), "\"missing mandatory parameter(s): '%s'\"", (nw == NULL && gw == NULL) ? "network, gateway" : (nw == NULL) ? "network" : "gateway"); rc = LUSTRE_CFG_RC_MISSING_PARAM; goto out; } net = libcfs_str2net(nw); if (net == LNET_NIDNET(LNET_NID_ANY)) { snprintf(err_str, sizeof(err_str), "\"cannot parse net %s\"", nw); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } if (LNET_NETTYP(net) == CIBLND || LNET_NETTYP(net) == OPENIBLND || LNET_NETTYP(net) == IIBLND || LNET_NETTYP(net) == VIBLND) { snprintf(err_str, sizeof(err_str), "\"obselete LNet type '%s'\"", libcfs_lnd2str(net)); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } gateway_nid = libcfs_str2nid(gw); if (gateway_nid == LNET_NID_ANY) { snprintf(err_str, sizeof(err_str), "\"cannot parse gateway NID '%s'\"", gw); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } if (hops == -1) { /* hops is undefined */ hops = LNET_UNDEFINED_HOPS; } else if (hops < 1 || hops > 255) { snprintf(err_str, sizeof(err_str), "\"invalid hop count %d, must be between 1 and 255\"", hops); rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM; goto out; } if (prio == -1) { prio = 0; } else if (prio < 0) { snprintf(err_str, sizeof(err_str), "\"invalid priority %d, must be greater than 0\"", prio); rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM; goto out; } LIBCFS_IOC_INIT_V2(data, cfg_hdr); data.cfg_net = net; data.cfg_config_u.cfg_route.rtr_hop = hops; data.cfg_config_u.cfg_route.rtr_priority = prio; data.cfg_nid = gateway_nid; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_ROUTE, &data); if (rc != 0) { rc = -errno; snprintf(err_str, sizeof(err_str), "\"cannot add route: %s\"", strerror(errno)); goto out; } out: cYAML_build_error(rc, seq_no, ADD_CMD, "route", err_str, err_rc); return rc; }
int lustre_lnet_show_route(char *nw, char *gw, int hops, int prio, int detail, int seq_no, struct cYAML **show_rc, struct cYAML **err_rc) { struct lnet_ioctl_config_data data; lnet_nid_t gateway_nid; int rc = LUSTRE_CFG_RC_OUT_OF_MEM; int l_errno = 0; __u32 net = LNET_NIDNET(LNET_NID_ANY); int i; struct cYAML *root = NULL, *route = NULL, *item = NULL; struct cYAML *first_seq = NULL; char err_str[LNET_MAX_STR_LEN]; bool exist = false; snprintf(err_str, sizeof(err_str), "\"out of memory\""); if (nw != NULL) { net = libcfs_str2net(nw); if (net == LNET_NIDNET(LNET_NID_ANY)) { snprintf(err_str, sizeof(err_str), "\"cannot parse net '%s'\"", nw); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } if (LNET_NETTYP(net) == CIBLND || LNET_NETTYP(net) == OPENIBLND || LNET_NETTYP(net) == IIBLND || LNET_NETTYP(net) == VIBLND) { snprintf(err_str, sizeof(err_str), "\"obsolete LNet type '%s'\"", libcfs_lnd2str(net)); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } } else { /* show all routes without filtering on net */ net = LNET_NIDNET(LNET_NID_ANY); } if (gw != NULL) { gateway_nid = libcfs_str2nid(gw); if (gateway_nid == LNET_NID_ANY) { snprintf(err_str, sizeof(err_str), "\"cannot parse gateway NID '%s'\"", gw); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } } else /* show all routes with out filtering on gateway */ gateway_nid = LNET_NID_ANY; if ((hops < 1 && hops != -1) || hops > 255) { snprintf(err_str, sizeof(err_str), "\"invalid hop count %d, must be between 0 and 256\"", hops); rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM; goto out; } /* create struct cYAML root object */ root = cYAML_create_object(NULL, NULL); if (root == NULL) goto out; route = cYAML_create_seq(root, "route"); if (route == NULL) goto out; for (i = 0;; i++) { LIBCFS_IOC_INIT_V2(data, cfg_hdr); data.cfg_count = i; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_ROUTE, &data); if (rc != 0) { l_errno = errno; break; } /* filter on provided data */ if (net != LNET_NIDNET(LNET_NID_ANY) && net != data.cfg_net) continue; if (gateway_nid != LNET_NID_ANY && gateway_nid != data.cfg_nid) continue; if (hops != -1 && hops != data.cfg_config_u.cfg_route.rtr_hop) continue; if (prio != -1 && prio != data.cfg_config_u.cfg_route.rtr_priority) continue; /* default rc to -1 incase we hit the goto */ rc = -1; exist = true; item = cYAML_create_seq_item(route); if (item == NULL) goto out; if (first_seq == NULL) first_seq = item; if (cYAML_create_string(item, "net", libcfs_net2str(data.cfg_net)) == NULL) goto out; if (cYAML_create_string(item, "gateway", libcfs_nid2str(data.cfg_nid)) == NULL) goto out; if (detail) { if (cYAML_create_number(item, "hop", data.cfg_config_u.cfg_route. rtr_hop) == NULL) goto out; if (cYAML_create_number(item, "priority", data.cfg_config_u. cfg_route.rtr_priority) == NULL) goto out; if (cYAML_create_string(item, "state", data.cfg_config_u.cfg_route. rtr_flags ? "up" : "down") == NULL) goto out; } } /* print output iff show_rc is not provided */ if (show_rc == NULL) cYAML_print_tree(root); if (l_errno != ENOENT) { snprintf(err_str, sizeof(err_str), "\"cannot get routes: %s\"", strerror(l_errno)); rc = -l_errno; goto out; } else rc = LUSTRE_CFG_RC_NO_ERR; snprintf(err_str, sizeof(err_str), "\"success\""); out: if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR || !exist) { cYAML_free_tree(root); } else if (show_rc != NULL && *show_rc != NULL) { struct cYAML *show_node; /* find the route node, if one doesn't exist then * insert one. Otherwise add to the one there */ show_node = cYAML_get_object_item(*show_rc, "route"); if (show_node != NULL && cYAML_is_sequence(show_node)) { cYAML_insert_child(show_node, first_seq); free(route); free(root); } else if (show_node == NULL) { cYAML_insert_sibling((*show_rc)->cy_child, route); free(root); } else { cYAML_free_tree(root); } } else { *show_rc = root; } cYAML_build_error(rc, seq_no, SHOW_CMD, "route", err_str, err_rc); return rc; }
int lustre_lnet_del_route(char *nw, char *gw, int seq_no, struct cYAML **err_rc) { struct lnet_ioctl_config_data data; lnet_nid_t gateway_nid; int rc = LUSTRE_CFG_RC_NO_ERR; __u32 net = LNET_NIDNET(LNET_NID_ANY); char err_str[LNET_MAX_STR_LEN]; snprintf(err_str, sizeof(err_str), "\"Success\""); if (nw == NULL || gw == NULL) { snprintf(err_str, sizeof(err_str), "\"missing mandatory parameter(s): '%s'\"", (nw == NULL && gw == NULL) ? "network, gateway" : (nw == NULL) ? "network" : "gateway"); rc = LUSTRE_CFG_RC_MISSING_PARAM; goto out; } net = libcfs_str2net(nw); if (net == LNET_NIDNET(LNET_NID_ANY)) { snprintf(err_str, sizeof(err_str), "\"cannot parse net '%s'\"", nw); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } if (LNET_NETTYP(net) == CIBLND || LNET_NETTYP(net) == OPENIBLND || LNET_NETTYP(net) == IIBLND || LNET_NETTYP(net) == VIBLND) { snprintf(err_str, sizeof(err_str), "\"obselete LNet type '%s'\"", libcfs_lnd2str(net)); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } gateway_nid = libcfs_str2nid(gw); if (gateway_nid == LNET_NID_ANY) { snprintf(err_str, sizeof(err_str), "\"cannot parse gateway NID '%s'\"", gw); rc = LUSTRE_CFG_RC_BAD_PARAM; goto out; } LIBCFS_IOC_INIT_V2(data, cfg_hdr); data.cfg_net = net; data.cfg_nid = gateway_nid; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_ROUTE, &data); if (rc != 0) { rc = -errno; snprintf(err_str, sizeof(err_str), "\"cannot delete route: %s\"", strerror(errno)); goto out; } out: cYAML_build_error(rc, seq_no, DEL_CMD, "route", err_str, err_rc); return rc; }
static int parse_perm_line(struct identity_downcall_data *data, char *line, size_t size) { char uid_str[size]; char nid_str[size]; char perm_str[size]; lnet_nid_t nid; __u32 perm, noperm; int rc, i; if (data->idd_nperms >= N_PERMS_MAX) { errlog("permission count %d > max %d\n", data->idd_nperms, N_PERMS_MAX); return -1; } rc = sscanf(line, "%s %s %s", nid_str, uid_str, perm_str); if (rc != 3) { errlog("can't parse line %s\n", line); return -1; } if (!match_uid(data->idd_uid, uid_str)) return 0; if (!strcmp(nid_str, "*")) { nid = LNET_NID_ANY; } else { nid = libcfs_str2nid(nid_str); if (nid == LNET_NID_ANY) { errlog("can't parse nid %s\n", nid_str); return -1; } } if (parse_perm(&perm, &noperm, perm_str)) { errlog("invalid perm %s\n", perm_str); return -1; } /* merge the perms with the same nid. * * If there is LNET_NID_ANY in data->idd_perms[i].pdd_nid, * it must be data->idd_perms[0].pdd_nid, and act as default perm. */ if (nid != LNET_NID_ANY) { int found = 0; /* search for the same nid */ for (i = data->idd_nperms - 1; i >= 0; i--) { if (data->idd_perms[i].pdd_nid == nid) { data->idd_perms[i].pdd_perm = (data->idd_perms[i].pdd_perm | perm) & ~noperm; found = 1; break; } } /* NOT found, add to tail */ if (!found) { data->idd_perms[data->idd_nperms].pdd_nid = nid; data->idd_perms[data->idd_nperms].pdd_perm = perm & ~noperm; data->idd_nperms++; } } else { if (data->idd_nperms > 0) { /* the first one isn't LNET_NID_ANY, need exchange */ if (data->idd_perms[0].pdd_nid != LNET_NID_ANY) { data->idd_perms[data->idd_nperms].pdd_nid = data->idd_perms[0].pdd_nid; data->idd_perms[data->idd_nperms].pdd_perm = data->idd_perms[0].pdd_perm; data->idd_perms[0].pdd_nid = LNET_NID_ANY; data->idd_perms[0].pdd_perm = perm & ~noperm; data->idd_nperms++; } else { /* only fix LNET_NID_ANY item */ data->idd_perms[0].pdd_perm = (data->idd_perms[0].pdd_perm | perm) & ~noperm; } } else { /* it is the first one, only add to head */ data->idd_perms[0].pdd_nid = LNET_NID_ANY; data->idd_perms[0].pdd_perm = perm & ~noperm; data->idd_nperms = 1; } } return 0; }
int liblustre_process_log(struct config_llog_instance *cfg, char *mgsnid, char *profile, int allow_recov) { struct lustre_cfg_bufs bufs; struct lustre_cfg *lcfg; char *peer = "MGS_UUID"; struct obd_device *obd; struct obd_export *exp; char *name = "mgc_dev"; class_uuid_t uuid; struct obd_uuid mgc_uuid; struct llog_ctxt *ctxt; lnet_nid_t nid = 0; char *mdsnid; int err, rc = 0; struct obd_connect_data *ocd = NULL; ENTRY; ll_generate_random_uuid(uuid); class_uuid_unparse(uuid, &mgc_uuid); nid = libcfs_str2nid(mgsnid); if (nid == LNET_NID_ANY) { CERROR("Can't parse NID %s\n", mgsnid); RETURN(-EINVAL); } lustre_cfg_bufs_reset(&bufs, NULL); lustre_cfg_bufs_set_string(&bufs, 1, peer); lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs); lcfg->lcfg_nid = nid; rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc < 0) GOTO(out, rc); lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MGC_NAME); lustre_cfg_bufs_set_string(&bufs, 2, mgc_uuid.uuid); lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs); rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc < 0) GOTO(out_del_uuid, rc); lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_MGS_OBDNAME); lustre_cfg_bufs_set_string(&bufs, 2, peer); lcfg = lustre_cfg_new(LCFG_SETUP, &bufs); rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc < 0) GOTO(out_detach, rc); while ((mdsnid = strsep(&mgsnid, ","))) { nid = libcfs_str2nid(mdsnid); lustre_cfg_bufs_reset(&bufs, NULL); lustre_cfg_bufs_set_string(&bufs, 1, libcfs_nid2str(nid)); lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs); lcfg->lcfg_nid = nid; rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc) { CERROR("Add uuid for %s failed %d\n", libcfs_nid2str(nid), rc); continue; } lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, libcfs_nid2str(nid)); lcfg = lustre_cfg_new(LCFG_ADD_CONN, &bufs); lcfg->lcfg_nid = nid; rc = class_process_config(lcfg); lustre_cfg_free(lcfg); if (rc) { CERROR("Add conn for %s failed %d\n", libcfs_nid2str(nid), rc); continue; } } obd = class_name2obd(name); if (obd == NULL) GOTO(out_cleanup, rc = -EINVAL); OBD_ALLOC(ocd, sizeof(*ocd)); if (ocd == NULL) GOTO(out_cleanup, rc = -ENOMEM); ocd->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT | OBD_CONNECT_FULL20; ocd->ocd_version = LUSTRE_VERSION_CODE; rc = obd_connect(NULL, &exp, obd, &mgc_uuid, ocd, NULL); if (rc) { CERROR("cannot connect to %s at %s: rc = %d\n", LUSTRE_MGS_OBDNAME, mgsnid, rc); GOTO(out_cleanup, rc); } ctxt = llog_get_context(exp->exp_obd, LLOG_CONFIG_REPL_CTXT); cfg->cfg_flags |= CFG_F_COMPAT146; rc = class_config_parse_llog(NULL, ctxt, profile, cfg); llog_ctxt_put(ctxt); if (rc) { CERROR("class_config_parse_llog failed: rc = %d\n", rc); } /* We don't so much care about errors in cleaning up the config llog * connection, as we have already read the config by this point. */ err = obd_disconnect(exp); if (err) CERROR("obd_disconnect failed: rc = %d\n", err); out_cleanup: if (ocd) OBD_FREE(ocd, sizeof(*ocd)); lustre_cfg_bufs_reset(&bufs, name); lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs); err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err) CERROR("md_cleanup failed: rc = %d\n", err); out_detach: lustre_cfg_bufs_reset(&bufs, name); lcfg = lustre_cfg_new(LCFG_DETACH, &bufs); err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err) CERROR("md_detach failed: rc = %d\n", err); out_del_uuid: lustre_cfg_bufs_reset(&bufs, name); lustre_cfg_bufs_set_string(&bufs, 1, peer); lcfg = lustre_cfg_new(LCFG_DEL_UUID, &bufs); err = class_process_config(lcfg); if (err) CERROR("del MDC UUID failed: rc = %d\n", err); lustre_cfg_free(lcfg); out: RETURN(rc); }
static int connect_echo_client(void) { struct lustre_cfg *lcfg; struct lustre_cfg_bufs bufs; lnet_nid_t nid; char *peer = "ECHO_PEER_NID"; class_uuid_t osc_uuid, echo_uuid; struct obd_uuid osc_uuid_str, echo_uuid_str; int err; ENTRY; ll_generate_random_uuid(osc_uuid); class_uuid_unparse(osc_uuid, &osc_uuid_str); ll_generate_random_uuid(echo_uuid); class_uuid_unparse(echo_uuid, &echo_uuid_str); nid = libcfs_str2nid(echo_server_nid); if (nid == LNET_NID_ANY) { CERROR("Can't parse NID %s\n", echo_server_nid); RETURN(-EINVAL); } /* add uuid */ lustre_cfg_bufs_reset(&bufs, NULL); lustre_cfg_bufs_set_string(&bufs, 1, peer); lcfg = lustre_cfg_new(LCFG_ADD_UUID, &bufs); lcfg->lcfg_nid = nid; err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err < 0) { CERROR("failed add_uuid\n"); RETURN(-EINVAL); } /* attach osc */ lustre_cfg_bufs_reset(&bufs, osc_dev_name); lustre_cfg_bufs_set_string(&bufs, 1, LUSTRE_OSC_NAME); lustre_cfg_bufs_set_string(&bufs, 2, osc_uuid_str.uuid); lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs); err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err < 0) { CERROR("failed attach osc\n"); RETURN(-EINVAL); } /* setup osc */ lustre_cfg_bufs_reset(&bufs, osc_dev_name); lustre_cfg_bufs_set_string(&bufs, 1, echo_server_ostname); lustre_cfg_bufs_set_string(&bufs, 2, peer); lcfg = lustre_cfg_new(LCFG_SETUP, &bufs); err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err < 0) { CERROR("failed setup osc\n"); RETURN(-EINVAL); } /* attach echo_client */ lustre_cfg_bufs_reset(&bufs, echo_dev_name); lustre_cfg_bufs_set_string(&bufs, 1, "echo_client"); lustre_cfg_bufs_set_string(&bufs, 2, echo_uuid_str.uuid); lcfg = lustre_cfg_new(LCFG_ATTACH, &bufs); err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err < 0) { CERROR("failed attach echo_client\n"); RETURN(-EINVAL); } /* setup echo_client */ lustre_cfg_bufs_reset(&bufs, echo_dev_name); lustre_cfg_bufs_set_string(&bufs, 1, osc_dev_name); lustre_cfg_bufs_set_string(&bufs, 2, NULL); lcfg = lustre_cfg_new(LCFG_SETUP, &bufs); err = class_process_config(lcfg); lustre_cfg_free(lcfg); if (err < 0) { CERROR("failed setup echo_client\n"); RETURN(-EINVAL); } RETURN(0); }
/** * Turns a lctl parameter string into a procfs/sysfs subdirectory path pattern. * * \param[in] popt Used to control parameter usage. For this * function it is used to see if the path has * a added suffix. * \param[in,out] path lctl parameter string that is turned into * the subdirectory path pattern that is used * to search the procfs/sysfs tree. * * \retval -errno on error. */ static int clean_path(struct param_opts *popt, char *path) { char *nidstr = NULL; char *tmp; if (popt == NULL || path == NULL || strlen(path) == 0) return -EINVAL; /* If path contains a suffix we need to remove it */ if (popt->po_show_type) { size_t path_end = strlen(path) - 1; tmp = path + path_end; switch (*tmp) { case '@': case '=': case '/': *tmp = '\0'; default: break; } } /* get rid of '\', glob doesn't like it */ tmp = strrchr(path, '\\'); if (tmp != NULL) { char *tail = path + strlen(path); while (tmp != path) { if (*tmp == '\\') { memmove(tmp, tmp + 1, tail - tmp); --tail; } --tmp; } } /* Does this path contain a NID string ? */ tmp = strchr(path, '@'); if (tmp != NULL) { char *find_nid = strdup(path); lnet_nid_t nid; if (find_nid == NULL) return -ENOMEM; /* First we need to chop off rest after nid string. * Since find_nid is a clone of path it better have * '@' */ tmp = strchr(find_nid, '@'); tmp = strchr(tmp, '.'); if (tmp != NULL) *tmp = '\0'; /* Now chop off the front. */ for (tmp = strchr(find_nid, '.'); tmp != NULL; tmp = strchr(tmp, '.')) { /* Remove MGC to make it NID format */ if (!strncmp(++tmp, "MGC", 3)) tmp += 3; nid = libcfs_str2nid(tmp); if (nid != LNET_NID_ANY) { nidstr = libcfs_nid2str(nid); if (nidstr == NULL) return -EINVAL; break; } } free(find_nid); } /* replace param '.' with '/' */ for (tmp = strchr(path, '.'); tmp != NULL; tmp = strchr(tmp, '.')) { *tmp++ = '/'; /* Remove MGC to make it NID format */ if (!strncmp(tmp, "MGC", 3)) tmp += 3; /* There exist cases where some of the subdirectories of the * the parameter tree has embedded in its name a NID string. * This means that it is possible that these subdirectories * could have actual '.' in its name. If this is the case we * don't want to blindly replace the '.' with '/'. */ if (nidstr != NULL) { char *match = strstr(tmp, nidstr); if (tmp == match) tmp += strlen(nidstr); } } return 0; }