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 + -
显示快捷键?