int lustre_lnet_enable_routing(int enable, int seq_no, struct cYAML **err_rc) { struct lnet_ioctl_config_data data; int rc = LUSTRE_CFG_RC_NO_ERR; char err_str[LNET_MAX_STR_LEN]; snprintf(err_str, sizeof(err_str), "\"success\""); LIBCFS_IOC_INIT_V2(data, cfg_hdr); data.cfg_config_u.cfg_buffers.buf_enable = (enable) ? 1 : 0; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_CONFIG_RTR, &data); if (rc != 0) { rc = -errno; snprintf(err_str, sizeof(err_str), "\"cannot %s routing %s\"", (enable) ? "enable" : "disable", strerror(errno)); goto out; } out: cYAML_build_error(rc, seq_no, (enable) ? ADD_CMD : DEL_CMD, "routing", err_str, err_rc); return rc; }
/* We can't use the libptlctl library fns because they are not shared-memory safe with respect to the ioctl device (cur_dev) */ static int obj_ioctl(int cmd, struct obd_ioctl_data *data, int unpack) { char *buf = NULL; int rc; //IOC_PACK(cmdname, data); if (obd_ioctl_pack(data, &buf, sizeof(*data))) { fprintf(stderr, "dev %d invalid ioctl\n", data->ioc_dev); rc = EINVAL; goto out; } rc = l_ioctl(OBD_DEV_ID, cmd, buf); if (unpack) { //IOC_UNPACK(argv[0], data); if (obd_ioctl_unpack(data, buf, sizeof(*data))) { fprintf(stderr, "dev %d invalid reply\n", data->ioc_dev); rc = EINVAL; goto out; } } out: if (buf) free(buf); return rc; }
int lustre_lnet_config_ni_system(bool up, bool load_ni_from_mod, int seq_no, struct cYAML **err_rc) { struct libcfs_ioctl_data data; unsigned int opc; int rc; char err_str[LNET_MAX_STR_LEN]; snprintf(err_str, sizeof(err_str), "\"Success\""); LIBCFS_IOC_INIT(data); /* Reverse logic is used here in order not to change * the lctl utility */ data.ioc_flags = load_ni_from_mod ? 0 : 1; opc = up ? IOC_LIBCFS_CONFIGURE : IOC_LIBCFS_UNCONFIGURE; rc = l_ioctl(LNET_DEV_ID, opc, &data); if (rc != 0) { snprintf(err_str, sizeof(err_str), "\"LNet %s error: %s\"", (up) ? "configure" : "unconfigure", strerror(errno)); rc = -errno; } cYAML_build_error(rc, seq_no, (up) ? CONFIG_CMD : UNCONFIG_CMD, "lnet", err_str, err_rc); return rc; }
int jt_lfsck_stop(int argc, char **argv) { struct obd_ioctl_data data; char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char device[MAX_OBD_NAME]; char *optstring = "M:h"; int opt, index, rc; memset(&data, 0, sizeof(data)); memset(device, 0, MAX_OBD_NAME); /* Reset the 'optind' for the case of getopt_long() called multiple * times under the same lctl. */ optind = 0; while ((opt = getopt_long(argc, argv, optstring, long_opt_stop, &index)) != EOF) { switch (opt) { case 'M': rc = lfsck_pack_dev(&data, device, optarg); if (rc != 0) return rc; break; case 'h': usage_stop(); return 0; default: fprintf(stderr, "Invalid option, '-h' for help.\n"); return -EINVAL; } } if (data.ioc_inlbuf4 == NULL) { if (lcfg_get_devname() != NULL) { rc = lfsck_pack_dev(&data, device, lcfg_get_devname()); if (rc != 0) return rc; } else { fprintf(stderr, "Must specify device to stop LFSCK.\n"); return -EINVAL; } } memset(buf, 0, sizeof(rawbuf)); rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc); return rc; } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_STOP_LFSCK, buf); if (rc < 0) { perror("Fail to stop LFSCK"); return rc; } printf("Stopped LFSCK on the device %s.\n", device); return 0; }
int jt_dbg_mark_debug_buf(int argc, char **argv) { static char scratch[MAX_MARK_SIZE] = ""; struct libcfs_ioctl_data data; char *text; int rc; memset(&data, 0, sizeof(data)); if (argc > 1) { int count, max_size = sizeof(scratch) - 1; strncpy(scratch, argv[1], max_size); max_size -= strlen(argv[1]); for (count = 2; (count < argc) && (max_size > 1); count++) { strncat(scratch, " ", max_size); max_size -= 1; strncat(scratch, argv[count], max_size); max_size -= strlen(argv[count]); } scratch[sizeof(scratch) - 1] = '\0'; text = scratch; } else { time_t now = time(NULL); text = ctime(&now); } data.ioc_inllen1 = strlen(text) + 1; data.ioc_inlbuf1 = text; if (libcfs_ioctl_pack(&data, &buf, max) != 0) { fprintf(stderr, "libcfs_ioctl_pack failed.\n"); return -1; } rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_MARK_DEBUG, buf); if (rc) { fprintf(stderr, "IOC_LIBCFS_MARK_DEBUG failed: %s\n", strerror(errno)); return -1; } return 0; }
int lustre_lnet_del_net(char *nw, int seq_no, struct cYAML **err_rc) { struct lnet_ioctl_config_data data; __u32 net = LNET_NIDNET(LNET_NID_ANY); int rc = LUSTRE_CFG_RC_NO_ERR; char err_str[LNET_MAX_STR_LEN]; snprintf(err_str, sizeof(err_str), "\"success\""); if (nw == NULL) { snprintf(err_str, sizeof(err_str), "\"missing mandatory parameter\""); 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; } LIBCFS_IOC_INIT_V2(data, cfg_hdr); data.cfg_net = net; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_DEL_NET, &data); if (rc != 0) { rc = -errno; snprintf(err_str, sizeof(err_str), "\"cannot delete network: %s\"", strerror(errno)); goto out; } out: cYAML_build_error(rc, seq_no, DEL_CMD, "net", err_str, err_rc); return rc; }
int lustre_lnet_config_buffers(int tiny, int small, int large, int seq_no, struct cYAML **err_rc) { struct lnet_ioctl_config_data data; int rc = LUSTRE_CFG_RC_NO_ERR; char err_str[LNET_MAX_STR_LEN]; snprintf(err_str, sizeof(err_str), "\"success\""); /* -1 indicates to ignore changes to this field */ if (tiny < -1 || small < -1 || large < -1) { snprintf(err_str, sizeof(err_str), "\"tiny, small and large must be >= 0\""); rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM; goto out; } LIBCFS_IOC_INIT_V2(data, cfg_hdr); data.cfg_config_u.cfg_buffers.buf_tiny = tiny; data.cfg_config_u.cfg_buffers.buf_small = small; data.cfg_config_u.cfg_buffers.buf_large = large; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_BUF, &data); if (rc != 0) { rc = -errno; snprintf(err_str, sizeof(err_str), "\"cannot configure buffers: %s\"", strerror(errno)); goto out; } out: cYAML_build_error(rc, seq_no, ADD_CMD, "buf", err_str, err_rc); return rc; }
int jt_dbg_panic(int argc, char **argv) { int rc; struct libcfs_ioctl_data data; if (argc != 1) { fprintf(stderr, "usage: %s\n", argv[0]); return 0; } memset(&data, 0, sizeof(data)); if (libcfs_ioctl_pack(&data, &buf, max) != 0) { fprintf(stderr, "libcfs_ioctl_pack failed.\n"); return -1; } rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_PANIC, buf); if (rc) { fprintf(stderr, "IOC_LIBCFS_PANIC failed: %s\n", strerror(errno)); return -1; } return 0; }
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_routing(int seq_no, struct cYAML **show_rc, struct cYAML **err_rc) { struct lnet_ioctl_config_data *data; struct lnet_ioctl_pool_cfg *pool_cfg = NULL; int rc = LUSTRE_CFG_RC_OUT_OF_MEM; int l_errno = 0; char *buf; char *pools[LNET_NRBPOOLS] = {"tiny", "small", "large"}; int buf_count[LNET_NRBPOOLS] = {0}; struct cYAML *root = NULL, *pools_node = NULL, *type_node = NULL, *item = NULL, *cpt = NULL, *first_seq = NULL, *buffers = NULL; int i, j; char err_str[LNET_MAX_STR_LEN]; char node_name[LNET_MAX_STR_LEN]; bool exist = false; snprintf(err_str, sizeof(err_str), "\"out of memory\""); buf = calloc(1, sizeof(*data) + sizeof(*pool_cfg)); if (buf == NULL) goto out; data = (struct lnet_ioctl_config_data *)buf; root = cYAML_create_object(NULL, NULL); if (root == NULL) goto out; pools_node = cYAML_create_seq(root, "routing"); if (pools_node == NULL) goto out; for (i = 0;; i++) { LIBCFS_IOC_INIT_V2(*data, cfg_hdr); data->cfg_hdr.ioc_len = sizeof(struct lnet_ioctl_config_data) + sizeof(struct lnet_ioctl_pool_cfg); data->cfg_count = i; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_BUF, data); if (rc != 0) { l_errno = errno; break; } exist = true; pool_cfg = (struct lnet_ioctl_pool_cfg *)data->cfg_bulk; snprintf(node_name, sizeof(node_name), "cpt[%d]", i); item = cYAML_create_seq_item(pools_node); if (item == NULL) goto out; if (first_seq == NULL) first_seq = item; cpt = cYAML_create_object(item, node_name); if (cpt == NULL) goto out; /* create the tree and print */ for (j = 0; j < LNET_NRBPOOLS; j++) { type_node = cYAML_create_object(cpt, pools[j]); if (type_node == NULL) goto out; if (cYAML_create_number(type_node, "npages", pool_cfg->pl_pools[j].pl_npages) == NULL) goto out; if (cYAML_create_number(type_node, "nbuffers", pool_cfg->pl_pools[j]. pl_nbuffers) == NULL) goto out; if (cYAML_create_number(type_node, "credits", pool_cfg->pl_pools[j]. pl_credits) == NULL) goto out; if (cYAML_create_number(type_node, "mincredits", pool_cfg->pl_pools[j]. pl_mincredits) == NULL) goto out; /* keep track of the total count for each of the * tiny, small and large buffers */ buf_count[j] += pool_cfg->pl_pools[j].pl_nbuffers; } } if (pool_cfg != NULL) { item = cYAML_create_seq_item(pools_node); if (item == NULL) goto out; if (cYAML_create_number(item, "enable", pool_cfg->pl_routing) == NULL) goto out; } /* create a buffers entry in the show. This is necessary so that * if the YAML output is used to configure a node, the buffer * configuration takes hold */ buffers = cYAML_create_object(root, "buffers"); if (buffers == NULL) goto out; for (i = 0; i < LNET_NRBPOOLS; i++) { if (cYAML_create_number(buffers, pools[i], buf_count[i]) == NULL) goto out; } if (show_rc == NULL) cYAML_print_tree(root); if (l_errno != ENOENT) { snprintf(err_str, sizeof(err_str), "\"cannot get routing information: %s\"", strerror(l_errno)); rc = -l_errno; goto out; } else rc = LUSTRE_CFG_RC_NO_ERR; snprintf(err_str, sizeof(err_str), "\"success\""); rc = LUSTRE_CFG_RC_NO_ERR; out: free(buf); 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 *routing_node; /* there should exist only one routing block and one * buffers block. If there already exists a previous one * then don't add another */ routing_node = cYAML_get_object_item(*show_rc, "routing"); if (routing_node == NULL) { cYAML_insert_sibling((*show_rc)->cy_child, root->cy_child); free(root); } else { cYAML_free_tree(root); } } else { *show_rc = root; } cYAML_build_error(rc, seq_no, SHOW_CMD, "routing", err_str, err_rc); return rc; }
int jt_lfsck_start(int argc, char **argv) { struct obd_ioctl_data data; char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char device[MAX_OBD_NAME]; struct lfsck_start start; char *optstring = "Ac::C::e:hM:n::ors:t:w:"; int opt, index, rc, val, i; memset(&data, 0, sizeof(data)); memset(&start, 0, sizeof(start)); memset(device, 0, MAX_OBD_NAME); start.ls_version = LFSCK_VERSION_V1; start.ls_active = LFSCK_TYPES_ALL; /* Reset the 'optind' for the case of getopt_long() called multiple * times under the same lctl. */ optind = 0; while ((opt = getopt_long(argc, argv, optstring, long_opt_start, &index)) != EOF) { switch (opt) { case 'A': start.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST; break; case 'c': if (optarg == NULL || strcmp(optarg, "on") == 0) { start.ls_flags |= LPF_CREATE_OSTOBJ; } else if (strcmp(optarg, "off") != 0) { fprintf(stderr, "invalid switch: -c '%s'. " "valid switches are:\n" "empty ('on'), or 'off' without space. " "For example:\n" "'-c', '-con', '-coff'\n", optarg); return -EINVAL; } start.ls_valid |= LSV_CREATE_OSTOBJ; break; case 'C': if (optarg == NULL || strcmp(optarg, "on") == 0) { start.ls_flags |= LPF_CREATE_MDTOBJ; } else if (strcmp(optarg, "off") != 0) { fprintf(stderr, "invalid switch: -C '%s'. " "valid switches are:\n" "empty ('on'), or 'off' without space. " "For example:\n" "'-C', '-Con', '-Coff'\n", optarg); return -EINVAL; } start.ls_valid |= LSV_CREATE_MDTOBJ; break; case 'e': if (strcmp(optarg, "abort") == 0) { start.ls_flags |= LPF_FAILOUT; } else if (strcmp(optarg, "continue") != 0) { fprintf(stderr, "invalid error mode: -e '%s'." "valid modes are: " "'continue' or 'abort'.\n", optarg); return -EINVAL; } start.ls_valid |= LSV_ERROR_HANDLE; break; case 'h': usage_start(); return 0; case 'M': rc = lfsck_pack_dev(&data, device, optarg); if (rc != 0) return rc; break; case 'n': if (optarg == NULL || strcmp(optarg, "on") == 0) { start.ls_flags |= LPF_DRYRUN; } else if (strcmp(optarg, "off") != 0) { fprintf(stderr, "invalid switch: -n '%s'. " "valid switches are:\n" "empty ('on'), or 'off' without space. " "For example:\n" "'-n', '-non', '-noff'\n", optarg); return -EINVAL; } start.ls_valid |= LSV_DRYRUN; break; case 'o': start.ls_flags |= LPF_ALL_TGT | LPF_BROADCAST | LPF_OST_ORPHAN; break; case 'r': start.ls_flags |= LPF_RESET; break; case 's': val = atoi(optarg); start.ls_speed_limit = val; start.ls_valid |= LSV_SPEED_LIMIT; break; case 't': { char *typename; if (start.ls_active == LFSCK_TYPES_ALL) start.ls_active = 0; while ((typename = strsep(&optarg, ",")) != NULL) { enum lfsck_type type; type = lfsck_name2type(typename); if (type == -1) goto bad_type; start.ls_active |= type; } break; bad_type: fprintf(stderr, "invalid check type -t '%s'. " "valid types are:\n", typename); for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++) fprintf(stderr, "%s%s", i != 0 ? "," : "", lfsck_types_names[i].ltn_name); fprintf(stderr, "\n"); return -EINVAL; } case 'w': val = atoi(optarg); if (val < 1 || val > LFSCK_ASYNC_WIN_MAX) { fprintf(stderr, "Invalid async window size that " "may cause memory issues. The valid " "range is [1 - %u].\n", LFSCK_ASYNC_WIN_MAX); return -EINVAL; } start.ls_async_windows = val; start.ls_valid |= LSV_ASYNC_WINDOWS; break; default: fprintf(stderr, "Invalid option, '-h' for help.\n"); return -EINVAL; } } if (start.ls_active == LFSCK_TYPES_ALL) start.ls_active = LFSCK_TYPES_DEF; if (data.ioc_inlbuf4 == NULL) { if (lcfg_get_devname() != NULL) { rc = lfsck_pack_dev(&data, device, lcfg_get_devname()); if (rc != 0) return rc; } else { fprintf(stderr, "Must specify device to start LFSCK.\n"); return -EINVAL; } } data.ioc_inlbuf1 = (char *)&start; data.ioc_inllen1 = sizeof(start); memset(buf, 0, sizeof(rawbuf)); rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc); return rc; } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_START_LFSCK, buf); if (rc < 0) { perror("Fail to start LFSCK"); return rc; } obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); printf("Started LFSCK on the device %s: scrub", device); for (i = 0; lfsck_types_names[i].ltn_name != NULL; i++) { if (start.ls_active & lfsck_types_names[i].ltn_type) { printf(" %s", lfsck_types_names[i].ltn_name); start.ls_active &= ~lfsck_types_names[i].ltn_type; } } if (start.ls_active != 0) printf(" unknown(0x%x)", start.ls_active); printf("\n"); return 0; }
int lustre_lnet_config_net(char *net, char *intf, char *ip2net, int peer_to, int peer_cr, int peer_buf_cr, int credits, char *smp, int seq_no, struct lnet_ioctl_config_lnd_tunables *lnd_tunables, struct cYAML **err_rc) { struct lnet_ioctl_config_lnd_tunables *lnd = NULL; struct lnet_ioctl_config_data *data; size_t ioctl_size = sizeof(*data); char buf[LNET_MAX_STR_LEN]; int rc = LUSTRE_CFG_RC_NO_ERR; char err_str[LNET_MAX_STR_LEN]; snprintf(err_str, sizeof(err_str), "\"success\""); /* No need to register lo */ if (net != NULL && !strcmp(net, "lo")) return 0; if (ip2net == NULL && (intf == NULL || net == NULL)) { snprintf(err_str, sizeof(err_str), "\"mandatory parameter '%s' not specified." " Optionally specify ip2net parameter\"", (intf == NULL && net == NULL) ? "net, if" : (intf == NULL) ? "if" : "net"); rc = LUSTRE_CFG_RC_MISSING_PARAM; goto out; } if (peer_to != -1 && peer_to <= 0) { snprintf(err_str, sizeof(err_str), "\"peer timeout %d, must be greater than 0\"", peer_to); rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM; goto out; } if (ip2net != NULL && strlen(ip2net) >= sizeof(buf)) { snprintf(err_str, sizeof(err_str), "\"ip2net string too long %d\"", (int)strlen(ip2net)); rc = LUSTRE_CFG_RC_OUT_OF_RANGE_PARAM; goto out; } if (lnd_tunables != NULL) ioctl_size += sizeof(*lnd_tunables); data = calloc(1, ioctl_size); if (data == NULL) goto out; if (ip2net == NULL) snprintf(buf, sizeof(buf) - 1, "%s(%s)%s", net, intf, (smp) ? smp : ""); LIBCFS_IOC_INIT_V2(*data, cfg_hdr); strncpy(data->cfg_config_u.cfg_net.net_intf, (ip2net != NULL) ? ip2net : buf, sizeof(buf)); data->cfg_config_u.cfg_net.net_peer_timeout = peer_to; data->cfg_config_u.cfg_net.net_peer_tx_credits = peer_cr; data->cfg_config_u.cfg_net.net_peer_rtr_credits = peer_buf_cr; data->cfg_config_u.cfg_net.net_max_tx_credits = credits; /* Add in tunable settings if available */ if (lnd_tunables != NULL) { lnd = (struct lnet_ioctl_config_lnd_tunables *)data->cfg_bulk; data->cfg_hdr.ioc_len = ioctl_size; memcpy(lnd, lnd_tunables, sizeof(*lnd_tunables)); } rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_ADD_NET, data); if (rc < 0) { rc = -errno; snprintf(err_str, sizeof(err_str), "\"cannot add network: %s\"", strerror(errno)); } free(data); out: cYAML_build_error(rc, seq_no, ADD_CMD, "net", 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; }
int lustre_lnet_show_stats(int seq_no, struct cYAML **show_rc, struct cYAML **err_rc) { struct lnet_ioctl_lnet_stats data; int rc = LUSTRE_CFG_RC_OUT_OF_MEM; int l_errno; char err_str[LNET_MAX_STR_LEN]; struct cYAML *root = NULL, *stats = NULL; snprintf(err_str, sizeof(err_str), "\"out of memory\""); LIBCFS_IOC_INIT_V2(data, st_hdr); rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_LNET_STATS, &data); if (rc != 0) { l_errno = errno; snprintf(err_str, sizeof(err_str), "\"cannot get lnet statistics: %s\"", strerror(l_errno)); rc = -l_errno; goto out; } root = cYAML_create_object(NULL, NULL); if (root == NULL) goto out; stats = cYAML_create_object(root, "statistics"); if (stats == NULL) goto out; if (cYAML_create_number(stats, "msgs_alloc", data.st_cntrs.msgs_alloc) == NULL) goto out; if (cYAML_create_number(stats, "msgs_max", data.st_cntrs.msgs_max) == NULL) goto out; if (cYAML_create_number(stats, "errors", data.st_cntrs.errors) == NULL) goto out; if (cYAML_create_number(stats, "send_count", data.st_cntrs.send_count) == NULL) goto out; if (cYAML_create_number(stats, "recv_count", data.st_cntrs.recv_count) == NULL) goto out; if (cYAML_create_number(stats, "route_count", data.st_cntrs.route_count) == NULL) goto out; if (cYAML_create_number(stats, "drop_count", data.st_cntrs.drop_count) == NULL) goto out; if (cYAML_create_number(stats, "send_length", data.st_cntrs.send_length) == NULL) goto out; if (cYAML_create_number(stats, "recv_length", data.st_cntrs.recv_length) == NULL) goto out; if (cYAML_create_number(stats, "route_length", data.st_cntrs.route_length) == NULL) goto out; if (cYAML_create_number(stats, "drop_length", data.st_cntrs.drop_length) == NULL) goto out; if (show_rc == NULL) cYAML_print_tree(root); snprintf(err_str, sizeof(err_str), "\"success\""); out: if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) { cYAML_free_tree(root); } else if (show_rc != NULL && *show_rc != NULL) { cYAML_insert_sibling((*show_rc)->cy_child, root->cy_child); free(root); } else { *show_rc = root; } cYAML_build_error(rc, seq_no, SHOW_CMD, "statistics", err_str, err_rc); return rc; }
int lustre_lnet_show_peer_credits(int seq_no, struct cYAML **show_rc, struct cYAML **err_rc) { struct lnet_ioctl_peer peer_info; int rc = LUSTRE_CFG_RC_OUT_OF_MEM, ncpt = 0, i = 0, j = 0; int l_errno = 0; struct cYAML *root = NULL, *peer = NULL, *first_seq = NULL, *peer_root = NULL; char err_str[LNET_MAX_STR_LEN]; bool ncpt_set = false; snprintf(err_str, sizeof(err_str), "\"out of memory\""); /* create struct cYAML root object */ root = cYAML_create_object(NULL, NULL); if (root == NULL) goto out; peer_root = cYAML_create_seq(root, "peer"); if (peer_root == NULL) goto out; do { for (i = 0;; i++) { LIBCFS_IOC_INIT_V2(peer_info, pr_hdr); peer_info.pr_count = i; peer_info.pr_lnd_u.pr_peer_credits.cr_ncpt = j; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_PEER_INFO, &peer_info); if (rc != 0) { l_errno = errno; break; } if (ncpt_set != 0) { ncpt = peer_info.pr_lnd_u.pr_peer_credits. cr_ncpt; ncpt_set = true; } peer = cYAML_create_seq_item(peer_root); if (peer == NULL) goto out; if (first_seq == NULL) first_seq = peer; if (cYAML_create_string(peer, "nid", libcfs_nid2str (peer_info.pr_nid)) == NULL) goto out; if (cYAML_create_string(peer, "state", peer_info.pr_lnd_u. pr_peer_credits. cr_aliveness) == NULL) goto out; if (cYAML_create_number(peer, "refcount", peer_info.pr_lnd_u. pr_peer_credits. cr_refcount) == NULL) goto out; if (cYAML_create_number(peer, "max_ni_tx_credits", peer_info.pr_lnd_u. pr_peer_credits. cr_ni_peer_tx_credits) == NULL) goto out; if (cYAML_create_number(peer, "available_tx_credits", peer_info.pr_lnd_u. pr_peer_credits. cr_peer_tx_credits) == NULL) goto out; if (cYAML_create_number(peer, "available_rtr_credits", peer_info.pr_lnd_u. pr_peer_credits. cr_peer_rtr_credits) == NULL) goto out; if (cYAML_create_number(peer, "min_rtr_credits", peer_info.pr_lnd_u. pr_peer_credits. cr_peer_min_rtr_credits) == NULL) goto out; if (cYAML_create_number(peer, "tx_q_num_of_buf", peer_info.pr_lnd_u. pr_peer_credits. cr_peer_tx_qnob) == NULL) goto out; } if (l_errno != ENOENT) { snprintf(err_str, sizeof(err_str), "\"cannot get peer information: %s\"", strerror(l_errno)); rc = -l_errno; goto out; } j++; } while (j < ncpt); /* print output iff show_rc is not provided */ if (show_rc == NULL) cYAML_print_tree(root); snprintf(err_str, sizeof(err_str), "\"success\""); rc = LUSTRE_CFG_RC_NO_ERR; out: if (show_rc == NULL || rc != LUSTRE_CFG_RC_NO_ERR) { cYAML_free_tree(root); } else if (show_rc != NULL && *show_rc != NULL) { struct cYAML *show_node; /* find the peer node, if one doesn't exist then * insert one. Otherwise add to the one there */ show_node = cYAML_get_object_item(*show_rc, "peer_credits"); if (show_node != NULL && cYAML_is_sequence(show_node)) { cYAML_insert_child(show_node, first_seq); free(peer_root); free(root); } else if (show_node == NULL) { cYAML_insert_sibling((*show_rc)->cy_child, peer_root); free(root); } else { cYAML_free_tree(root); } } else { *show_rc = root; } cYAML_build_error(rc, seq_no, SHOW_CMD, "peer_credits", err_str, err_rc); return rc; }
int jt_lfsck_start(int argc, char **argv) { struct obd_ioctl_data data; char rawbuf[MAX_IOC_BUFLEN], *buf = rawbuf; char device[MAX_OBD_NAME]; struct lfsck_start start; char *optstring = "M:e:hn:rs:t:"; int opt, index, rc, val, i, type; memset(&data, 0, sizeof(data)); memset(&start, 0, sizeof(start)); memset(device, 0, MAX_OBD_NAME); start.ls_version = LFSCK_VERSION_V1; start.ls_active = LFSCK_TYPES_DEF; /* Reset the 'optind' for the case of getopt_long() called multiple * times under the same lctl. */ optind = 0; while ((opt = getopt_long(argc, argv, optstring, long_opt_start, &index)) != EOF) { switch (opt) { case 'M': rc = lfsck_pack_dev(&data, device, optarg); if (rc != 0) return rc; break; case 'e': if (strcmp(optarg, "abort") == 0) { start.ls_flags |= LPF_FAILOUT; } else if (strcmp(optarg, "continue") != 0) { fprintf(stderr, "Invalid error handler: %s. " "The valid value should be: 'continue'" "(default) or 'abort'.\n", optarg); return -EINVAL; } start.ls_valid |= LSV_ERROR_HANDLE; break; case 'h': usage_start(); return 0; case 'n': if (strcmp(optarg, "on") == 0) { start.ls_flags |= LPF_DRYRUN; } else if (strcmp(optarg, "off") != 0) { fprintf(stderr, "Invalid dryrun switch: %s. " "The valid value shou be: 'off'" "(default) or 'on'\n", optarg); return -EINVAL; } start.ls_valid |= LSV_DRYRUN; break; case 'r': start.ls_flags |= LPF_RESET; break; case 's': val = atoi(optarg); start.ls_speed_limit = val; start.ls_valid |= LSV_SPEED_LIMIT; break; case 't': { char *str = optarg, *p, c; start.ls_active = 0; while (*str) { while (*str == ' ' || *str == ',') str++; if (*str == 0) break; p = str; while (*p != 0 && *p != ' ' && *p != ',') p++; c = *p; *p = 0; type = lfsck_name2type(str, strlen(str)); if (type == 0) { fprintf(stderr, "Invalid type (%s).\n" "The valid value should be " "'layout', 'DNE' or " "'namespace'.\n", str); *p = c; return -EINVAL; } *p = c; str = p; start.ls_active |= type; } if (start.ls_active == 0) { fprintf(stderr, "Miss LFSCK type(s).\n" "The valid value should be " "'layout', 'DNE' or 'namespace'.\n"); return -EINVAL; } break; } default: fprintf(stderr, "Invalid option, '-h' for help.\n"); return -EINVAL; } } if (data.ioc_inlbuf4 == NULL) { fprintf(stderr, "Must sepcify MDT device to start LFSCK.\n"); return -EINVAL; } data.ioc_inlbuf1 = (char *)&start; data.ioc_inllen1 = sizeof(start); memset(buf, 0, sizeof(rawbuf)); rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf)); if (rc) { fprintf(stderr, "Fail to pack ioctl data: rc = %d.\n", rc); return rc; } rc = l_ioctl(OBD_DEV_ID, OBD_IOC_START_LFSCK, buf); if (rc < 0) { perror("Fail to start LFSCK"); return rc; } obd_ioctl_unpack(&data, buf, sizeof(rawbuf)); if (start.ls_active == 0) { printf("Started LFSCK on the MDT device %s", device); } else { printf("Started LFSCK on the MDT device %s:", device); i = 0; while (lfsck_types_names[i].name != NULL) { if (start.ls_active & lfsck_types_names[i].type) { printf(" %s", lfsck_types_names[i].name); start.ls_active &= ~lfsck_types_names[i].type; } i++; } if (start.ls_active != 0) printf(" unknown(0x%x)", start.ls_active); } printf(".\n"); return 0; }
int lustre_lnet_show_net(char *nw, int detail, int seq_no, struct cYAML **show_rc, struct cYAML **err_rc) { char *buf; struct lnet_ioctl_config_lnd_tunables *lnd_cfg; struct lnet_ioctl_config_data *data; struct lnet_ioctl_net_config *net_config; __u32 net = LNET_NIDNET(LNET_NID_ANY); int rc = LUSTRE_CFG_RC_OUT_OF_MEM, i, j; int l_errno = 0; struct cYAML *root = NULL, *tunables = NULL, *net_node = NULL, *interfaces = NULL, *item = NULL, *first_seq = NULL; int str_buf_len = LNET_MAX_SHOW_NUM_CPT * 2; char str_buf[str_buf_len]; char *pos; char err_str[LNET_MAX_STR_LEN]; bool exist = false; size_t buf_len; snprintf(err_str, sizeof(err_str), "\"out of memory\""); buf_len = sizeof(*data) + sizeof(*net_config) + sizeof(*lnd_cfg); buf = calloc(1, buf_len); if (buf == NULL) goto out; data = (struct lnet_ioctl_config_data *)buf; 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; } } root = cYAML_create_object(NULL, NULL); if (root == NULL) goto out; net_node = cYAML_create_seq(root, "net"); if (net_node == NULL) goto out; for (i = 0;; i++) { pos = str_buf; memset(buf, 0, buf_len); LIBCFS_IOC_INIT_V2(*data, cfg_hdr); /* * set the ioc_len to the proper value since INIT assumes * size of data */ data->cfg_hdr.ioc_len = buf_len; data->cfg_count = i; rc = l_ioctl(LNET_DEV_ID, IOC_LIBCFS_GET_NET, data); if (rc != 0) { l_errno = errno; break; } /* filter on provided data */ if (net != LNET_NIDNET(LNET_NID_ANY) && net != LNET_NIDNET(data->cfg_nid)) continue; /* default rc to -1 in case we hit the goto */ rc = -1; exist = true; net_config = (struct lnet_ioctl_net_config *)data->cfg_bulk; /* create the tree to be printed. */ item = cYAML_create_seq_item(net_node); if (item == NULL) goto out; if (first_seq == NULL) first_seq = item; if (cYAML_create_string(item, "net", libcfs_net2str( LNET_NIDNET(data->cfg_nid))) == NULL) goto out; if (cYAML_create_string(item, "nid", libcfs_nid2str(data->cfg_nid)) == NULL) goto out; if (cYAML_create_string(item, "status", (net_config->ni_status == LNET_NI_STATUS_UP) ? "up" : "down") == NULL) goto out; /* don't add interfaces unless there is at least one * interface */ if (strlen(net_config->ni_interfaces[0]) > 0) { interfaces = cYAML_create_object(item, "interfaces"); if (interfaces == NULL) goto out; for (j = 0; j < LNET_MAX_INTERFACES; j++) { if (lustre_interface_show_net(interfaces, j, detail, data, net_config) < 0) goto out; } } if (detail) { char *limit; tunables = cYAML_create_object(item, "tunables"); if (tunables == NULL) goto out; if (cYAML_create_number(tunables, "peer_timeout", data->cfg_config_u.cfg_net. net_peer_timeout) == NULL) goto out; if (cYAML_create_number(tunables, "peer_credits", data->cfg_config_u.cfg_net. net_peer_tx_credits) == NULL) goto out; if (cYAML_create_number(tunables, "peer_buffer_credits", data->cfg_config_u.cfg_net. net_peer_rtr_credits) == NULL) goto out; if (cYAML_create_number(tunables, "credits", data->cfg_config_u.cfg_net. net_max_tx_credits) == NULL) goto out; /* out put the CPTs in the format: "[x,x,x,...]" */ limit = str_buf + str_buf_len - 3; pos += snprintf(pos, limit - pos, "\"["); for (j = 0 ; data->cfg_ncpts > 1 && j < data->cfg_ncpts && pos < limit; j++) { pos += snprintf(pos, limit - pos, "%d", net_config->ni_cpts[j]); if ((j + 1) < data->cfg_ncpts) pos += snprintf(pos, limit - pos, ","); } pos += snprintf(pos, 3, "]\""); if (data->cfg_ncpts > 1 && cYAML_create_string(tunables, "CPT", str_buf) == NULL) goto out; } } /* Print out the net information only if 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 networks: %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 net node, if one doesn't exist * then insert one. Otherwise add to the one there */ show_node = cYAML_get_object_item(*show_rc, "net"); if (show_node != NULL && cYAML_is_sequence(show_node)) { cYAML_insert_child(show_node, first_seq); free(net_node); free(root); } else if (show_node == NULL) { cYAML_insert_sibling((*show_rc)->cy_child, net_node); free(root); } else { cYAML_free_tree(root); } } else { *show_rc = root; } cYAML_build_error(rc, seq_no, SHOW_CMD, "net", err_str, err_rc); return rc; }