⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 4 页
字号:
/* -*- 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 * * Infrastructure of LST console */#ifdef __KERNEL__#include <libcfs/libcfs.h>#include <lnet/lib-lnet.h>#include "console.h"#include "conrpc.h"#define LST_NODE_STATE_COUNTER(nd, p)                   \do {                                                    \        if ((nd)->nd_state == LST_NODE_ACTIVE)          \                (p)->nle_nactive ++;                    \        else if ((nd)->nd_state == LST_NODE_BUSY)       \                (p)->nle_nbusy ++;                      \        else if ((nd)->nd_state == LST_NODE_DOWN)       \                (p)->nle_ndown ++;                      \        else                                            \                (p)->nle_nunknown ++;                   \        (p)->nle_nnode ++;                              \} while (0)lstcon_session_t        console_session;voidlstcon_node_get(lstcon_node_t *nd){        LASSERT (nd->nd_ref >= 1);        nd->nd_ref++;}static intlstcon_node_find(lnet_process_id_t id, lstcon_node_t **ndpp, int create){        lstcon_ndlink_t *ndl;        unsigned int     idx = LNET_NIDADDR(id.nid) % LST_GLOBAL_HASHSIZE;        LASSERT (id.nid != LNET_NID_ANY);        list_for_each_entry(ndl, &console_session.ses_ndl_hash[idx], ndl_hlink) {                if (ndl->ndl_node->nd_id.nid != id.nid ||                    ndl->ndl_node->nd_id.pid != id.pid)                        continue;                lstcon_node_get(ndl->ndl_node);                *ndpp = ndl->ndl_node;                return 0;        }                if (!create)                return -ENOENT;        LIBCFS_ALLOC(*ndpp, sizeof(lstcon_node_t) + sizeof(lstcon_ndlink_t));        if (*ndpp == NULL)                return -ENOMEM;        ndl = (lstcon_ndlink_t *)(*ndpp + 1);        ndl->ndl_node = *ndpp;        ndl->ndl_node->nd_ref   = 1;        ndl->ndl_node->nd_id    = id;        ndl->ndl_node->nd_stamp = cfs_time_current();        ndl->ndl_node->nd_state = LST_NODE_UNKNOWN;        ndl->ndl_node->nd_timeout = 0;        memset(&ndl->ndl_node->nd_ping, 0, sizeof(lstcon_rpc_t));        /* queued in global hash & list, no refcount is taken by         * global hash & list, if caller release his refcount,         * node will be released */        list_add_tail(&ndl->ndl_hlink, &console_session.ses_ndl_hash[idx]);        list_add_tail(&ndl->ndl_link, &console_session.ses_ndl_list);        return 0;}voidlstcon_node_put(lstcon_node_t *nd){        lstcon_ndlink_t  *ndl;        LASSERT (nd->nd_ref > 0);        if (--nd->nd_ref > 0)                return;        ndl = (lstcon_ndlink_t *)(nd + 1);        LASSERT (!list_empty(&ndl->ndl_link));        LASSERT (!list_empty(&ndl->ndl_hlink));        /* remove from session */        list_del(&ndl->ndl_link);        list_del(&ndl->ndl_hlink);        LIBCFS_FREE(nd, sizeof(lstcon_node_t) + sizeof(lstcon_ndlink_t));}static intlstcon_ndlink_find(struct list_head *hash,                   lnet_process_id_t id, lstcon_ndlink_t **ndlpp, int create){        unsigned int     idx = LNET_NIDADDR(id.nid) % LST_NODE_HASHSIZE;        lstcon_ndlink_t *ndl;        lstcon_node_t   *nd;        int              rc;        if (id.nid == LNET_NID_ANY)                return -EINVAL;        /* search in hash */        list_for_each_entry(ndl, &hash[idx], ndl_hlink) {                if (ndl->ndl_node->nd_id.nid != id.nid ||                    ndl->ndl_node->nd_id.pid != id.pid)                        continue;                *ndlpp = ndl;                return 0;        }        if (create == 0)                return -ENOENT;        /* find or create in session hash */        rc = lstcon_node_find(id, &nd, (create == 1) ? 1 : 0);        if (rc != 0)                return rc;        LIBCFS_ALLOC(ndl, sizeof(lstcon_ndlink_t));        if (ndl == NULL) {                lstcon_node_put(nd);                return -ENOMEM;        }                *ndlpp = ndl;        ndl->ndl_node = nd;        CFS_INIT_LIST_HEAD(&ndl->ndl_link);        list_add_tail(&ndl->ndl_hlink, &hash[idx]);        return  0;}static voidlstcon_ndlink_release(lstcon_ndlink_t *ndl){        LASSERT (list_empty(&ndl->ndl_link));        LASSERT (!list_empty(&ndl->ndl_hlink));        list_del(&ndl->ndl_hlink); /* delete from hash */        lstcon_node_put(ndl->ndl_node);        LIBCFS_FREE(ndl, sizeof(*ndl));}static intlstcon_group_alloc(char *name, lstcon_group_t **grpp){        lstcon_group_t *grp;        int             i;        LIBCFS_ALLOC(grp, offsetof(lstcon_group_t,                                   grp_ndl_hash[LST_NODE_HASHSIZE]));        if (grp == NULL)                return -ENOMEM;        memset(grp, 0, offsetof(lstcon_group_t,                                grp_ndl_hash[LST_NODE_HASHSIZE]));        grp->grp_ref = 1;        if (name != NULL)                strcpy(grp->grp_name, name);        CFS_INIT_LIST_HEAD(&grp->grp_link);        CFS_INIT_LIST_HEAD(&grp->grp_ndl_list);        CFS_INIT_LIST_HEAD(&grp->grp_trans_list);        for (i = 0; i < LST_NODE_HASHSIZE; i++)                CFS_INIT_LIST_HEAD(&grp->grp_ndl_hash[i]);        *grpp = grp;        return 0;}static voidlstcon_group_addref(lstcon_group_t *grp){        grp->grp_ref ++;}static void lstcon_group_ndlink_release(lstcon_group_t *, lstcon_ndlink_t *);static voidlstcon_group_drain(lstcon_group_t *grp, int keep){        lstcon_ndlink_t *ndl;        lstcon_ndlink_t *tmp;        list_for_each_entry_safe(ndl, tmp, &grp->grp_ndl_list, ndl_link) {                if ((ndl->ndl_node->nd_state & keep) == 0)                        lstcon_group_ndlink_release(grp, ndl);        }}static voidlstcon_group_decref(lstcon_group_t *grp){        int     i;        if (--grp->grp_ref > 0)                return;        if (!list_empty(&grp->grp_link))                list_del(&grp->grp_link);        lstcon_group_drain(grp, 0);        for (i = 0; i < LST_NODE_HASHSIZE; i++) {                LASSERT (list_empty(&grp->grp_ndl_hash[i]));        }        LIBCFS_FREE(grp, offsetof(lstcon_group_t,                                  grp_ndl_hash[LST_NODE_HASHSIZE]));}static intlstcon_group_find(char *name, lstcon_group_t **grpp){        lstcon_group_t   *grp;        list_for_each_entry(grp, &console_session.ses_grp_list, grp_link) {                if (strncmp(grp->grp_name, name, LST_NAME_SIZE) != 0)                        continue;                lstcon_group_addref(grp);  /* +1 ref for caller */                *grpp = grp;                return 0;        }        return -ENOENT;}static voidlstcon_group_put(lstcon_group_t *grp){        lstcon_group_decref(grp);}static intlstcon_group_ndlink_find(lstcon_group_t *grp, lnet_process_id_t id,                         lstcon_ndlink_t **ndlpp, int create){        int     rc;                rc = lstcon_ndlink_find(&grp->grp_ndl_hash[0], id, ndlpp, create);        if (rc != 0)                return rc;        if (!list_empty(&(*ndlpp)->ndl_link))                return 0;        list_add_tail(&(*ndlpp)->ndl_link, &grp->grp_ndl_list);        grp->grp_nnode ++;        return 0;}static voidlstcon_group_ndlink_release(lstcon_group_t *grp, lstcon_ndlink_t *ndl){        list_del_init(&ndl->ndl_link);        lstcon_ndlink_release(ndl);        grp->grp_nnode --;}static voidlstcon_group_ndlink_move(lstcon_group_t *old,                         lstcon_group_t *new, lstcon_ndlink_t *ndl){        unsigned int idx = LNET_NIDADDR(ndl->ndl_node->nd_id.nid) %                           LST_NODE_HASHSIZE;        list_del(&ndl->ndl_hlink);        list_del(&ndl->ndl_link);        old->grp_nnode --;        list_add_tail(&ndl->ndl_hlink, &new->grp_ndl_hash[idx]);        list_add_tail(&ndl->ndl_link, &new->grp_ndl_list);        new->grp_nnode ++;        return;}static voidlstcon_group_move(lstcon_group_t *old, lstcon_group_t *new){        lstcon_ndlink_t *ndl;        while (!list_empty(&old->grp_ndl_list)) {                ndl = list_entry(old->grp_ndl_list.next,                                 lstcon_ndlink_t, ndl_link);                lstcon_group_ndlink_move(old, new, ndl);        }}intlstcon_sesrpc_condition(int transop, lstcon_node_t *nd, void *arg){        lstcon_group_t *grp = (lstcon_group_t *)arg;        switch (transop) {        case LST_TRANS_SESNEW:                if (nd->nd_state == LST_NODE_ACTIVE)                        return 0;                break;        case LST_TRANS_SESEND:                if (nd->nd_state != LST_NODE_ACTIVE)                        return 0;                if (grp != NULL && nd->nd_ref > 1)                        return 0;                break;        case LST_TRANS_SESQRY:                break;        default:                LBUG();        }        return 1;}intlstcon_sesrpc_readent(int transop, srpc_msg_t *msg,                      lstcon_rpc_ent_t *ent_up){        srpc_debug_reply_t *rep;        switch (transop) {        case LST_TRANS_SESNEW:        case LST_TRANS_SESEND:                return 0;        case LST_TRANS_SESQRY:                rep = &msg->msg_body.dbg_reply;                if (copy_to_user(&ent_up->rpe_priv[0],                                 &rep->dbg_timeout, sizeof(int)) ||                    copy_to_user(&ent_up->rpe_payload[0],                                 &rep->dbg_name, LST_NAME_SIZE))                        return -EFAULT;                return 0;        default:                LBUG();        }        return 0;}static intlstcon_group_nodes_add(lstcon_group_t *grp, int count,                       lnet_process_id_t *ids_up, struct list_head *result_up){        lstcon_rpc_trans_t      *trans;        lstcon_ndlink_t         *ndl;        lstcon_group_t          *tmp;        lnet_process_id_t        id;        int                      i;        int                      rc;        rc = lstcon_group_alloc(NULL, &tmp);        if (rc != 0) {                CERROR("Out of memory\n");                return -ENOMEM;        }        for (i = 0 ; i < count; i++) {                if (copy_from_user(&id, &ids_up[i], sizeof(id))) {                        rc = -EFAULT;                        break;                }                /* skip if it's in this group already */                rc = lstcon_group_ndlink_find(grp, id, &ndl, 0);                if (rc == 0)                        continue;                /* add to tmp group */                rc = lstcon_group_ndlink_find(tmp, id, &ndl, 1);                if (rc != 0) {                        CERROR("Can't create ndlink, out of memory\n");                        break;                }        }        if (rc != 0) {                lstcon_group_put(tmp);                return rc;        }        rc = lstcon_rpc_trans_ndlist(&tmp->grp_ndl_list,                                     &tmp->grp_trans_list, LST_TRANS_SESNEW,                                     tmp, lstcon_sesrpc_condition, &trans);        if (rc != 0) {                CERROR("Can't create transaction: %d\n", rc);                lstcon_group_put(tmp);                return rc;        }        /* post all RPCs */        lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);                rc = lstcon_rpc_trans_interpreter(trans, result_up,                                          lstcon_sesrpc_readent);        /* destroy all RPGs */        lstcon_rpc_trans_destroy(trans);        lstcon_group_move(tmp, grp);        lstcon_group_put(tmp);        return rc;}static intlstcon_group_nodes_remove(lstcon_group_t *grp,                          int count, lnet_process_id_t *ids_up,                          struct list_head *result_up){        lstcon_rpc_trans_t     *trans;        lstcon_ndlink_t        *ndl;        lstcon_group_t         *tmp;        lnet_process_id_t       id;        int                     rc;        int                     i;        /* End session and remove node from the group */        rc = lstcon_group_alloc(NULL, &tmp);        if (rc != 0) {                CERROR("Out of memory\n");                return -ENOMEM;        }        for (i = 0; i < count; i++) {                if (copy_from_user(&id, &ids_up[i], sizeof(id))) {                        rc = -EFAULT;                        goto error;                }                                /* move node to tmp group */                if (lstcon_group_ndlink_find(grp, id, &ndl, 0) == 0)                        lstcon_group_ndlink_move(grp, tmp, ndl);        }        rc = lstcon_rpc_trans_ndlist(&tmp->grp_ndl_list,                                     &tmp->grp_trans_list, LST_TRANS_SESEND,                                     tmp, lstcon_sesrpc_condition, &trans);        if (rc != 0) {                CERROR("Can't create transaction: %d\n", rc);                goto error;        }        lstcon_rpc_trans_postwait(trans, LST_TRANS_TIMEOUT);        rc = lstcon_rpc_trans_interpreter(trans, result_up, NULL);        lstcon_rpc_trans_destroy(trans);        /* release nodes anyway, because we can't rollback status */        lstcon_group_put(tmp);        return rc;error:        lstcon_group_move(tmp, grp);        lstcon_group_put(tmp);        return rc;}intlstcon_group_add(char *name){        lstcon_group_t *grp;        int             rc;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -