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

📄 api-ni.c

📁 lustre 1.6.5 source code
💻 C
📖 第 1 页 / 共 4 页
字号:
                return rc;        case IOC_LIBCFS_FAIL_NID:                return lnet_fail_nid(data->ioc_nid, data->ioc_count);                        case IOC_LIBCFS_ADD_ROUTE:                rc = lnet_add_route(data->ioc_net, data->ioc_count,                                     data->ioc_nid);                return (rc != 0) ? rc : lnet_check_routes();                        case IOC_LIBCFS_DEL_ROUTE:                return lnet_del_route(data->ioc_net, data->ioc_nid);        case IOC_LIBCFS_GET_ROUTE:                return lnet_get_route(data->ioc_count,                                       &data->ioc_net, &data->ioc_count,                                       &data->ioc_nid, &data->ioc_flags);        case IOC_LIBCFS_NOTIFY_ROUTER:                return lnet_notify(NULL, data->ioc_nid, data->ioc_flags,                                    (time_t)data->ioc_u64[0]);        case IOC_LIBCFS_PORTALS_COMPATIBILITY:                return the_lnet.ln_ptlcompat;        case IOC_LIBCFS_LNET_DIST:                rc = LNetDist(data->ioc_nid, &data->ioc_nid, &data->ioc_u32[1]);                if (rc < 0 && rc != -EHOSTUNREACH)                        return rc;                                data->ioc_u32[0] = rc;                return 0;        case IOC_LIBCFS_TESTPROTOCOMPAT:                LNET_LOCK();                the_lnet.ln_testprotocompat = data->ioc_flags;                LNET_UNLOCK();                return 0;        case IOC_LIBCFS_PING:                rc = lnet_ping((lnet_process_id_t) {.nid = data->ioc_nid,                                                    .pid = data->ioc_u32[0]},                               data->ioc_u32[1], /* timeout */                               (lnet_process_id_t *)data->ioc_pbuf1,                               data->ioc_plen1/sizeof(lnet_process_id_t));                if (rc < 0)                        return rc;                data->ioc_count = rc;                return 0;        case IOC_LIBCFS_DEBUG_PEER: {                /* CAVEAT EMPTOR: this one designed for calling directly; not                 * via an ioctl */                lnet_process_id_t *id = arg;                lnet_debug_peer(id->nid);                ni = lnet_net2ni(LNET_NIDNET(id->nid));                if (ni == NULL) {                        CDEBUG(D_WARNING, "No NI for %s\n", libcfs_id2str(*id));                } else {                        if (ni->ni_lnd->lnd_ctl == NULL) {                                CDEBUG(D_WARNING, "No ctl for %s\n",                                       libcfs_id2str(*id));                        } else {                                (void)ni->ni_lnd->lnd_ctl(ni, cmd, arg);                        }                                                lnet_ni_decref(ni);                }                return 0;        }                        default:                ni = lnet_net2ni(data->ioc_net);                if (ni == NULL)                        return -EINVAL;                if (ni->ni_lnd->lnd_ctl == NULL)                        rc = -EINVAL;                else                        rc = ni->ni_lnd->lnd_ctl(ni, cmd, arg);                lnet_ni_decref(ni);                return rc;        }        /* not reached */}intLNetGetId(unsigned int index, lnet_process_id_t *id){        lnet_ni_t        *ni;        struct list_head *tmp;        int               rc = -ENOENT;        LASSERT (the_lnet.ln_init);        LASSERT (the_lnet.ln_refcount > 0);        LNET_LOCK();        list_for_each(tmp, &the_lnet.ln_nis) {                if (index-- != 0)                        continue;                                ni = list_entry(tmp, lnet_ni_t, ni_list);                id->nid = ni->ni_nid;                id->pid = the_lnet.ln_pid;                rc = 0;                break;        }        LNET_UNLOCK();        return rc;}voidLNetSnprintHandle(char *str, int len, lnet_handle_any_t h){        snprintf(str, len, LPX64, h.cookie);}intlnet_ping_target_init(void){        lnet_handle_me_t  meh;        lnet_process_id_t id;        int               rc;        int               rc2;        int               n;        int               infosz;        int               i;                for (n = 0; ; n++) {                rc = LNetGetId(n, &id);                if (rc == -ENOENT)                        break;                LASSERT (rc == 0);        }        infosz = offsetof(lnet_ping_info_t, pi_nid[n]);        LIBCFS_ALLOC(the_lnet.ln_ping_info, infosz);        if (the_lnet.ln_ping_info == NULL) {                CERROR("Can't allocate ping info[%d]\n", n);                return -ENOMEM;        }        the_lnet.ln_ping_info->pi_magic   = LNET_PROTO_PING_MAGIC;        the_lnet.ln_ping_info->pi_version = LNET_PROTO_PING_VERSION;        the_lnet.ln_ping_info->pi_pid     = the_lnet.ln_pid;        the_lnet.ln_ping_info->pi_nnids   = n;        for (i = 0; i < n; i++) {                rc = LNetGetId(i, &id);                LASSERT (rc == 0);                the_lnet.ln_ping_info->pi_nid[i] = id.nid;        }                /* We can have a tiny EQ since we only need to see the unlink event on         * teardown, which by definition is the last one! */        rc = LNetEQAlloc(2, LNET_EQ_HANDLER_NONE, &the_lnet.ln_ping_target_eq);        if (rc != 0) {                CERROR("Can't allocate ping EQ: %d\n", rc);                goto failed_0;        }        rc = LNetMEAttach(LNET_RESERVED_PORTAL,                          (lnet_process_id_t){.nid = LNET_NID_ANY,                                              .pid = LNET_PID_ANY},                          LNET_PROTO_PING_MATCHBITS, 0LL,                          LNET_UNLINK, LNET_INS_AFTER,                          &meh);        if (rc != 0) {                CERROR("Can't create ping ME: %d\n", rc);                goto failed_1;        }        rc = LNetMDAttach(meh,                          (lnet_md_t){.start = the_lnet.ln_ping_info,                                      .length = infosz,                                      .threshold = LNET_MD_THRESH_INF,                                      .options = (LNET_MD_OP_GET |                                                  LNET_MD_TRUNCATE |                                                  LNET_MD_MANAGE_REMOTE),                                      .eq_handle = the_lnet.ln_ping_target_eq},                          LNET_RETAIN,                          &the_lnet.ln_ping_target_md);        if (rc != 0) {                CERROR("Can't attach ping MD: %d\n", rc);                goto failed_2;        }        return 0; failed_2:        rc2 = LNetMEUnlink(meh);        LASSERT (rc2 == 0); failed_1:        rc2 = LNetEQFree(the_lnet.ln_ping_target_eq);        LASSERT (rc2 == 0); failed_0:        LIBCFS_FREE(the_lnet.ln_ping_info, infosz);        return rc;}voidlnet_ping_target_fini(void){        lnet_event_t    event;        int             rc;        int             which;        int             timeout_ms = 1000;        cfs_sigset_t    blocked = cfs_block_allsigs();        LNetMDUnlink(the_lnet.ln_ping_target_md);        /* NB md could be busy; this just starts the unlink */        for (;;) {                rc = LNetEQPoll(&the_lnet.ln_ping_target_eq, 1,                                timeout_ms, &event, &which);                /* I expect overflow... */                LASSERT (rc >= 0 || rc == -EOVERFLOW);                if (rc == 0) {                        /* timed out: provide a diagnostic */                        CWARN("Still waiting for ping MD to unlink\n");                        timeout_ms *= 2;                        continue;                }                /* Got a valid event */                if (event.unlinked)                        break;        }        rc = LNetEQFree(the_lnet.ln_ping_target_eq);        LASSERT (rc == 0);        LIBCFS_FREE(the_lnet.ln_ping_info,                    offsetof(lnet_ping_info_t,                             pi_nid[the_lnet.ln_ping_info->pi_nnids]));        cfs_restore_sigs(blocked);}intlnet_ping (lnet_process_id_t id, int timeout_ms, lnet_process_id_t *ids, int n_ids){        lnet_handle_eq_t     eqh;        lnet_handle_md_t     mdh;        lnet_event_t         event;        int                  which;        int                  unlinked = 0;        int                  replied = 0;        const int            a_long_time = 60000; /* mS */        int                  infosz = offsetof(lnet_ping_info_t, pi_nid[n_ids]);        lnet_ping_info_t    *info;        lnet_process_id_t    tmpid;        int                  i;        int                  nob;        int                  rc;        int                  rc2;        cfs_sigset_t         blocked;        if (n_ids <= 0 ||            id.nid == LNET_NID_ANY ||            timeout_ms > 500000 ||              /* arbitrary limit! */            n_ids > 20)                         /* arbitrary limit! */                return -EINVAL;        if (id.pid == LNET_PID_ANY)                id.pid = LUSTRE_SRV_LNET_PID;        LIBCFS_ALLOC(info, infosz);        if (info == NULL)                return -ENOMEM;        /* NB 2 events max (including any unlink event) */        rc = LNetEQAlloc(2, LNET_EQ_HANDLER_NONE, &eqh);        if (rc != 0) {                CERROR("Can't allocate EQ: %d\n", rc);                goto out_0;        }        rc = LNetMDBind((lnet_md_t){.start = info,                                    .length = infosz,                                    .threshold = 2, /* GET/REPLY */                                    .options = LNET_MD_TRUNCATE,                                    .eq_handle = eqh},                        LNET_UNLINK,                        &mdh);        if (rc != 0) {                CERROR("Can't bind MD: %d\n", rc);                goto out_1;        }        rc = LNetGet(LNET_NID_ANY, mdh, id,                     LNET_RESERVED_PORTAL,                     LNET_PROTO_PING_MATCHBITS, 0);        if (rc != 0) {                /* Don't CERROR; this could be deliberate! */                rc2 = LNetMDUnlink(mdh);                LASSERT (rc2 == 0);                /* NB must wait for the UNLINK event below... */                unlinked = 1;                timeout_ms = a_long_time;        }        do {                /* MUST block for unlink to complete */                if (unlinked)                        blocked = cfs_block_allsigs();                rc2 = LNetEQPoll(&eqh, 1, timeout_ms, &event, &which);                if (unlinked)                        cfs_restore_sigs(blocked);                CDEBUG(D_NET, "poll %d(%d %d)%s\n", rc2,                       (rc2 <= 0) ? -1 : event.type,                       (rc2 <= 0) ? -1 : event.status,                       (rc2 > 0 && event.unlinked) ? " unlinked" : "");                LASSERT (rc2 != -EOVERFLOW);     /* can't miss anything */                if (rc2 <= 0 || event.status != 0) {                        /* timeout or error */                        if (!replied && rc == 0)                                rc = (rc2 < 0) ? rc2 :                                     (rc2 == 0) ? -ETIMEDOUT :                                     event.status;                        if (!unlinked) {                                /* Ensure completion in finite time... */                                LNetMDUnlink(mdh);                                /* No assertion (racing with network) */                                unlinked = 1;                                timeout_ms = a_long_time;                        } else if (rc2 == 0) {                                /* timed out waiting for unlink */                                CWARN("ping %s: late network completion\n",                                      libcfs_id2str(id));                        }                } else if (event.type == LNET_EVENT_REPLY) {                        replied = 1;                        rc = event.mlength;                }        } while (rc2 <= 0 || !event.unlinked);        if (!replied) {                if (rc >= 0)                        CWARN("%s: Unexpected rc >= 0 but no reply!\n",                              libcfs_id2str(id));                rc = -EIO;                goto out_1;        }        nob = rc;        LASSERT (nob >= 0 && nob <= infosz);        rc = -EPROTO;                           /* if I can't parse... */        if (nob < 8) {                /* can't check magic/version */                CERROR("%s: ping info too short %d\n",                       libcfs_id2str(id), nob);                goto out_1;        }        if (info->pi_magic == __swab32(LNET_PROTO_PING_MAGIC)) {                /* NB I might be swabbing garbage until I check below, but it                 * doesn't matter */                __swab32s(&info->pi_version);                __swab32s(&info->pi_pid);                __swab32s(&info->pi_nnids);                for (i = 0; i < info->pi_nnids && i < n_ids; i++)                        __swab64s(&info->pi_nid[i]);        } else if (info->pi_magic != LNET_PROTO_PING_MAGIC) {                CERROR("%s: Unexpected magic %08x\n",                        libcfs_id2str(id), info->pi_magic);                goto out_1;        }        if (info->pi_version != LNET_PROTO_PING_VERSION) {                CERROR("%s: Unexpected version 0x%x\n",                       libcfs_id2str(id), info->pi_version);                goto out_1;        }        if (nob < offsetof(lnet_ping_info_t, pi_nid[0])) {                CERROR("%s: Short reply %d(%d min)\n", libcfs_id2str(id),                        nob, (int)offsetof(lnet_ping_info_t, pi_nid[0]));                goto out_1;        }        if (info->pi_nnids < n_ids)                n_ids = info->pi_nnids;        if (nob < offsetof(lnet_ping_info_t, pi_nid[n_ids])) {                CERROR("%s: Short reply %d(%d expected)\n", libcfs_id2str(id),                        nob, (int)offsetof(lnet_ping_info_t, pi_nid[n_ids]));                goto out_1;        }        rc = -EFAULT;                           /* If I SEGV... */        for (i = 0; i < n_ids; i++) {                tmpid.pid = info->pi_pid;                tmpid.nid = info->pi_nid[i];#ifdef __KERNEL__                if (copy_to_user(&ids[i], &tmpid, sizeof(tmpid)))                        goto out_1;#else                ids[i] = tmpid;#endif        }        rc = info->pi_nnids; out_1:        rc2 = LNetEQFree(eqh);        if (rc2 != 0)                CERROR("rc2 %d\n", rc2);        LASSERT (rc2 == 0); out_0:        LIBCFS_FREE(info, infosz);        return rc;}

⌨️ 快捷键说明

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