lst.c
来自「lustre 1.6.5 source code」· C语言 代码 · 共 2,162 行 · 第 1/5 页
C
2,162 行
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Author: Liang Zhen <liangzhen@clusterfs.com> * * This file is part of Lustre, http://www.lustre.org */#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <errno.h>#include <pwd.h>#include <lnet/lnetctl.h>#include <lnet/lnetst.h>#include "parser.h"static command_t lst_cmdlist[];static lst_sid_t session_id;static int session_key; static lstcon_trans_stat_t trans_stat;typedef struct list_string { struct list_string *lstr_next; int lstr_sz; char lstr_str[0];} lstr_t;#define offsetof(typ,memb) ((unsigned long)((char *)&(((typ *)0)->memb)))static int alloc_count = 0;static int alloc_nob = 0;lstr_t *alloc_lstr(int sz){ lstr_t *lstr = malloc(offsetof(lstr_t, lstr_str[sz])); if (lstr == NULL) { fprintf(stderr, "Can't allocate lstr\n"); abort(); } alloc_nob += sz; alloc_count++; lstr->lstr_str[0] = 0; lstr->lstr_sz = sz; return lstr;}voidfree_lstr(lstr_t *lstr){ alloc_count--; alloc_nob -= lstr->lstr_sz; free(lstr);}voidfree_lstrs(lstr_t **list){ lstr_t *lstr; while ((lstr = *list) != NULL) { *list = lstr->lstr_next; free_lstr(lstr); }}voidnew_lstrs(lstr_t **list, char *prefix, char *postfix, int lo, int hi, int stride){ int n1 = strlen(prefix); int n2 = strlen(postfix); int sz = n1 + 20 + n2 + 1; do { lstr_t *n = alloc_lstr(sz); snprintf(n->lstr_str, sz - 1, "%s%u%s", prefix, lo, postfix); n->lstr_next = *list; *list = n; lo += stride; } while (lo <= hi);}intexpand_lstr(lstr_t **list, lstr_t *l){ int nob = strlen(l->lstr_str); char *b1; char *b2; char *expr; char *sep; int x; int y; int z; int n; b1 = strchr(l->lstr_str, '['); if (b1 == NULL) { l->lstr_next = *list; *list = l; return 0; } b2 = strchr(b1, ']'); if (b2 == NULL || b2 == b1 + 1) return -1; *b1++ = 0; *b2++ = 0; expr = b1; do { sep = strchr(expr, ','); if (sep != NULL) *sep++ = 0; nob = strlen(expr); n = nob; if (sscanf(expr, "%u%n", &x, &n) >= 1 && n == nob) { /* simple number */ new_lstrs(list, l->lstr_str, b2, x, x, 1); continue; } n = nob; if (sscanf(expr, "%u-%u%n", &x, &y, &n) >= 2 && n == nob && x < y) { /* simple range */ new_lstrs(list, l->lstr_str, b2, x, y, 1); continue; } n = nob; if (sscanf(expr, "%u-%u/%u%n", &x, &y, &z, &n) >= 3 && n == nob && x < y) { /* strided range */ new_lstrs(list, l->lstr_str, b2, x, y, z); continue; } /* syntax error */ return -1; } while ((expr = sep) != NULL); free_lstr(l); return 1;}intexpand_strs(char *str, lstr_t **head){ lstr_t *list = NULL; lstr_t *nlist; lstr_t *l; int rc = 0; int expanded; l = alloc_lstr(strlen(str) + 1); memcpy(l->lstr_str, str, strlen(str) + 1); l->lstr_next = NULL; list = l; do { expanded = 0; nlist = NULL; while ((l = list) != NULL) { list = l->lstr_next; rc = expand_lstr(&nlist, l); if (rc < 0) { fprintf(stderr, "Syntax error in \"%s\"\n", str); free_lstr(l); break; } expanded |= rc > 0; } /* re-order onto 'list' */ while ((l = nlist) != NULL) { nlist = l->lstr_next; l->lstr_next = list; list = l; } } while (expanded && rc > 0); if (rc >= 0) { *head = list; return 0; } while ((l = list) != NULL) { list = l->lstr_next; free_lstr(l); } return rc;}intlst_parse_nids(char *str, int *countp, lnet_process_id_t **idspp){ lstr_t *head = NULL; lstr_t *l; int c = 0; int i; int rc; rc = expand_strs(str, &head); if (rc != 0) goto out; l = head; while (l != NULL) { l = l->lstr_next; c++; } *idspp = malloc(c * sizeof(lnet_process_id_t)); if (*idspp == NULL) { fprintf(stderr, "Out of memory\n"); rc = -1; } *countp = c;out: i = 0; while ((l = head) != NULL) { head = l->lstr_next; if (rc == 0) { (*idspp)[i].nid = libcfs_str2nid(l->lstr_str); if ((*idspp)[i].nid == LNET_NID_ANY) { fprintf(stderr, "Invalid nid: %s\n", l->lstr_str); rc = -1; } (*idspp)[i].pid = LUSTRE_LNET_PID; i++; } free_lstr(l); } if (rc == 0) return 0; free(*idspp); *idspp = NULL; return rc;}char *lst_node_state2str(int state){ if (state == LST_NODE_ACTIVE) return "Active"; if (state == LST_NODE_BUSY) return "Busy"; if (state == LST_NODE_DOWN) return "Down"; return "Unknown";}intlst_node_str2state(char *str){ if (strcasecmp(str, "active") == 0) return LST_NODE_ACTIVE; if (strcasecmp(str, "busy") == 0) return LST_NODE_BUSY; if (strcasecmp(str, "down") == 0) return LST_NODE_DOWN; if (strcasecmp(str, "unknown") == 0) return LST_NODE_UNKNOWN; if (strcasecmp(str, "invalid") == 0) return (LST_NODE_UNKNOWN | LST_NODE_DOWN | LST_NODE_BUSY); return -1;}char *lst_test_type2name(int type){ if (type == LST_TEST_PING) return "ping"; if (type == LST_TEST_BULK) return "brw"; return "unknown";}intlst_test_name2type(char *name){ if (strcasecmp(name, "ping") == 0) return LST_TEST_PING; if (strcasecmp(name, "brw") == 0) return LST_TEST_BULK; return -1;}voidlst_print_usage(char *cmd){ Parser_printhelp(cmd);}voidlst_print_error(char *sub, const char *def_format, ...){ va_list ap; /* local error returned from kernel */ switch (errno) { case ESRCH: fprintf(stderr, "No session exists\n"); return; case ESHUTDOWN: fprintf(stderr, "Session is shutting down\n"); return; case EACCES: fprintf(stderr, "Unmatched session key or not root\n"); return; case ENOENT: fprintf(stderr, "Can't find %s in current session\n", sub); return; case EINVAL: fprintf(stderr, "Invalid parameters list in command line\n"); return; case EFAULT: fprintf(stderr, "Bad parameter address\n"); return; case EEXIST: fprintf(stderr, "%s already exists\n", sub); return; default: va_start(ap, def_format); vfprintf(stderr, def_format, ap); va_end(ap); return; }}voidlst_free_rpcent(struct list_head *head){ lstcon_rpc_ent_t *ent; while (!list_empty(head)) { ent = list_entry(head->next, lstcon_rpc_ent_t, rpe_link); list_del(&ent->rpe_link); free(ent); }}voidlst_reset_rpcent(struct list_head *head){ lstcon_rpc_ent_t *ent; list_for_each_entry(ent, head, rpe_link) { ent->rpe_sid = LST_INVALID_SID; ent->rpe_peer.nid = LNET_NID_ANY; ent->rpe_peer.pid = LNET_PID_ANY; ent->rpe_rpc_errno = ent->rpe_fwk_errno = 0; }}intlst_alloc_rpcent(struct list_head *head, int count, int offset){ lstcon_rpc_ent_t *ent; int i; for (i = 0; i < count; i++) { ent = malloc(offsetof(lstcon_rpc_ent_t, rpe_payload[offset])); if (ent == NULL) { lst_free_rpcent(head); return -1; } memset(ent, 0, offsetof(lstcon_rpc_ent_t, rpe_payload[offset])); ent->rpe_sid = LST_INVALID_SID; ent->rpe_peer.nid = LNET_NID_ANY; ent->rpe_peer.pid = LNET_PID_ANY; list_add(&ent->rpe_link, head); } return 0;}voidlst_print_transerr(struct list_head *head, char *optstr){ lstcon_rpc_ent_t *ent; list_for_each_entry(ent, head, rpe_link) { if (ent->rpe_rpc_errno == 0 && ent->rpe_fwk_errno == 0) continue; if (ent->rpe_rpc_errno != 0) { fprintf(stderr, "%s RPC failed on %s: %s\n", optstr, libcfs_id2str(ent->rpe_peer), strerror(ent->rpe_rpc_errno)); continue; } fprintf(stderr, "%s failed on %s: %s\n", optstr, libcfs_id2str(ent->rpe_peer), strerror(ent->rpe_fwk_errno)); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?