void slcfg_init_res(struct sl_resource *r) { struct resprof_mds_info *rpmi; struct sl_mds_peerinfo *sp; struct sl_mds_iosinfo *si; rpmi = res2rpmi(r); psc_mutex_init(&rpmi->rpmi_mutex); psc_waitq_init(&rpmi->rpmi_waitq, "rpmi"); if (r->res_type == SLREST_MDS) { rpmi->rpmi_info = sp = PSCALLOC(sizeof(*sp)); sp->sp_flags = SPF_NEED_JRNL_INIT; pfl_meter_init(&sp->sp_batchmeter, 0, "nsupd-%s", r->res_name); } else { rpmi->rpmi_info = si = PSCALLOC(sizeof(*si)); si->si_flags = SIF_NEED_JRNL_INIT; if (RES_ISFS(r)) pfl_meter_init(&si->si_batchmeter, 0, "reclaim-%s", r->res_name); if (r->res_flags & RESF_DISABLE_BIA) si->si_flags |= SIF_DISABLE_LEASE; } }
/* * Handle a NAMESPACE_UPDATE request from another MDS. */ int slm_rmm_handle_namespace_update(struct pscrpc_request *rq) { struct srt_update_entry *entryp; struct srm_update_req *mq; struct srm_update_rep *mp; struct sl_mds_peerinfo *p; struct sl_resource *res; struct sl_site *site; struct iovec iov; int i, len, count; SL_RSX_ALLOCREP(rq, mq, mp); count = mq->count; if (count <= 0 || mq->size > LNET_MTU) { mp->rc = -EINVAL; return (mp->rc); } iov.iov_len = mq->size; iov.iov_base = PSCALLOC(mq->size); mp->rc = slrpc_bulkserver(rq, BULK_GET_SINK, SRMM_BULK_PORTAL, &iov, 1); if (mp->rc) goto out; /* Search for the peer information by the given site ID. */ site = libsl_siteid2site(mq->siteid); p = NULL; if (site) SITE_FOREACH_RES(site, res, i) if (res->res_type == SLREST_MDS) { p = res2rpmi(res)->rpmi_info; break; } if (p == NULL) { psclog_info("fail to find site ID %d", mq->siteid); PFL_GOTOERR(out, mp->rc = -EINVAL); } /* * Iterate through the namespace update buffer and apply updates. * If we fail to apply an update, we still report success to our * peer because reporting an error does not help our cause. */ entryp = iov.iov_base; for (i = 0; i < count; i++) { slm_rmm_apply_update(entryp); len = UPDATE_ENTRY_LEN(entryp); entryp = PSC_AGP(entryp, len); } zfsslash2_wait_synced(0); out: PSCFREE(iov.iov_base); return (mp->rc); }
int slmctlparam_namespace_stats(int fd, struct psc_ctlmsghdr *mh, struct psc_ctlmsg_param *pcp, char **levels, int nlevels, __unusedx struct psc_ctlparam_node *pcn) { char p_site[SITE_NAME_MAX], p_act[32], p_op[32], p_field[32]; int site_found = 0, rc = 1, a_val, o_val, f_val; struct sl_resm *m; if (nlevels > 6) return (psc_ctlsenderr(fd, mh, "invalid field")); /* sys.namespace_stats.<site|#AGGR>.<activity>.<op>.<field> */ /* ex: sys.namespace_stats.#aggr.replay.mkdir.successes */ levels[0] = "sys"; levels[1] = "namespace_stats"; if (strlcpy(p_site, nlevels > 2 ? levels[2] : "*", sizeof(p_site)) >= sizeof(p_site)) return (psc_ctlsenderr(fd, mh, "invalid site")); if (strlcpy(p_act, nlevels > 3 ? levels[3] : "*", sizeof(p_act)) >= sizeof(p_act)) return (psc_ctlsenderr(fd, mh, "invalid activity")); if (strlcpy(p_op, nlevels > 4 ? levels[4] : "*", sizeof(p_op)) >= sizeof(p_op)) return (psc_ctlsenderr(fd, mh, "invalid op")); if (strlcpy(p_field, nlevels > 5 ? levels[5] : "*", sizeof(p_field)) >= sizeof(p_field)) return (psc_ctlsenderr(fd, mh, "invalid site")); a_val = lookup(slm_nslogst_acts, nitems(slm_nslogst_acts), p_act); o_val = lookup(slm_nslogst_ops, nitems(slm_nslogst_ops), p_op); f_val = lookup(slm_nslogst_fields, nitems(slm_nslogst_fields), p_field); if (a_val == -1 && strcmp(p_act, "*")) return (psc_ctlsenderr(fd, mh, "invalid namespace.stats activity: %s", p_act)); if (o_val == -1 && strcmp(p_op, "*")) return (psc_ctlsenderr(fd, mh, "invalid namespace.stats operation: %s", p_op)); if (f_val == -1 && strcmp(p_field, "*")) return (psc_ctlsenderr(fd, mh, "invalid namespace.stats field: %s", p_field)); if (strcasecmp(p_site, "#aggr") == 0 || strcmp(p_site, "*") == 0) { levels[2] = "#aggr"; rc = slmctlparam_namespace_stats_process(fd, mh, pcp, levels, &slm_nsstats_aggr, a_val, o_val, f_val); if (!rc || strcmp(p_site, "#aggr") == 0) return (rc); site_found = 1; } SL_MDS_WALK(m, struct sl_mds_peerinfo *peerinfo; if (strcasecmp(p_site, m->resm_site->site_name) && strcmp(p_site, "*")) continue; site_found = 1; peerinfo = res2rpmi(m->resm_res)->rpmi_info; if (peerinfo == NULL) continue; levels[2] = m->resm_site->site_name; rc = slmctlparam_namespace_stats_process(fd, mh, pcp, levels, &peerinfo->sp_stats, a_val, o_val, f_val); if (!rc || strcmp(p_site, m->resm_site->site_name) == 0) SL_MDS_WALK_SETLAST(); );
/* * Adjust the bandwidth estimate between two IONs. * @src: source resm. * @dst: destination resm. * @amt: adjustment amount in bytes. */ int resmpair_bw_adj(struct sl_resm *src, struct sl_resm *dst, int64_t amt, int rc) { int ret = 1; struct resprof_mds_info *r_min, *r_max; struct rpmi_ios *is, *id; int64_t src_total, dst_total; int64_t cap = (int64_t)slm_upsch_bandwidth; /* sort by addr to avoid deadlock */ r_min = MIN(res2rpmi(src->resm_res), res2rpmi(dst->resm_res)); r_max = MAX(res2rpmi(src->resm_res), res2rpmi(dst->resm_res)); RPMI_LOCK(r_min); RPMI_LOCK(r_max); is = res2rpmi_ios(src->resm_res); id = res2rpmi_ios(dst->resm_res); psc_assert(amt); /* reserve */ if (amt > 0) { if (cap) { src_total = is->si_repl_ingress_pending + is->si_repl_egress_pending + amt; dst_total = is->si_repl_ingress_pending + is->si_repl_egress_pending + amt; if ((src_total > cap * BW_UNITSZ) || dst_total > cap * BW_UNITSZ) { ret = 0; goto out; } } is->si_repl_egress_pending += amt; id->si_repl_ingress_pending += amt; psclog_diag("adjust bandwidth; src=%s dst=%s amt=%"PRId64, src->resm_name, dst->resm_name, amt); } /* unreserve */ if (amt < 0) { is->si_repl_egress_pending += amt; id->si_repl_ingress_pending += amt; psc_assert(is->si_repl_egress_pending >= 0); psc_assert(id->si_repl_ingress_pending >= 0); if (!rc) { is->si_repl_egress_aggr += -amt; id->si_repl_ingress_aggr += -amt; } /* * We released some bandwidth; wake anyone waiting for * some. */ #if 0 CSVC_WAKE(src->resm_csvc); CSVC_WAKE(dst->resm_csvc); #endif } out: RPMI_ULOCK(r_max); RPMI_ULOCK(r_min); return (ret); }