📄 mgc_request.c
字号:
} RETURN(rc); } if (KEY_IS(KEY_SET_INFO)) { struct mgs_send_param *msp; msp = (struct mgs_send_param *)val; rc = mgc_set_mgs_param(exp, msp); RETURN(rc); } RETURN(rc);}static int mgc_import_event(struct obd_device *obd, struct obd_import *imp, enum obd_import_event event){ int rc = 0; LASSERT(imp->imp_obd == obd); CDEBUG(D_MGC, "import event %#x\n", event); switch (event) { case IMP_EVENT_DISCON: /* MGC imports should not wait for recovery */ break; case IMP_EVENT_INACTIVE: break; case IMP_EVENT_INVALIDATE: { struct ldlm_namespace *ns = obd->obd_namespace; ldlm_namespace_cleanup(ns, LDLM_FL_LOCAL_ONLY); break; } case IMP_EVENT_ACTIVE: LCONSOLE_WARN("%s: Reactivating import\n", obd->obd_name); /* Clearing obd_no_recov allows us to continue pinging */ obd->obd_no_recov = 0; break; case IMP_EVENT_OCD: break; default: CERROR("Unknown import event %#x\n", event); LBUG(); } RETURN(rc);}static int mgc_llog_init(struct obd_device *obd, struct obd_device *tgt, int count, struct llog_catid *logid, struct obd_uuid *uuid){ struct llog_ctxt *ctxt; int rc; ENTRY; rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, tgt, 0, NULL, &llog_lvfs_ops); if (rc) RETURN(rc); rc = llog_setup(obd, LLOG_CONFIG_REPL_CTXT, tgt, 0, NULL, &llog_client_ops); if (rc == 0) { ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT); ctxt->loc_imp = obd->u.cli.cl_import; llog_ctxt_put(ctxt); } RETURN(rc);}static int mgc_llog_finish(struct obd_device *obd, int count){ int rc; ENTRY; rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_REPL_CTXT)); rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT)); RETURN(rc);}/* identical to mgs_log_is_empty */static int mgc_llog_is_empty(struct obd_device *obd, struct llog_ctxt *ctxt, char *name){ struct lvfs_run_ctxt saved; struct llog_handle *llh; int rc = 0; push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); rc = llog_create(ctxt, &llh, NULL, name); if (rc == 0) { llog_init_handle(llh, LLOG_F_IS_PLAIN, NULL); rc = llog_get_size(llh); llog_close(llh); } pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); /* header is record 1 */ return(rc <= 1);}static int mgc_copy_handler(struct llog_handle *llh, struct llog_rec_hdr *rec, void *data){ struct llog_rec_hdr local_rec = *rec; struct llog_handle *local_llh = (struct llog_handle *)data; char *cfg_buf = (char*) (rec + 1); struct lustre_cfg *lcfg; int rc = 0; ENTRY; /* Append all records */ local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail); rc = llog_write_rec(local_llh, &local_rec, NULL, 0, (void *)cfg_buf, -1); lcfg = (struct lustre_cfg *)cfg_buf; CDEBUG(D_INFO, "idx=%d, rc=%d, len=%d, cmd %x %s %s\n", rec->lrh_index, rc, rec->lrh_len, lcfg->lcfg_command, lustre_cfg_string(lcfg, 0), lustre_cfg_string(lcfg, 1)); RETURN(rc);}/* Copy a remote log locally */static int mgc_copy_llog(struct obd_device *obd, struct llog_ctxt *rctxt, struct llog_ctxt *lctxt, char *logname){ struct llog_handle *local_llh, *remote_llh; struct obd_uuid *uuid; char *temp_log; int rc, rc2; ENTRY; /* Write new log to a temp name, then vfs_rename over logname upon successful completion. */ OBD_ALLOC(temp_log, strlen(logname) + 1); if (!temp_log) RETURN(-ENOMEM); sprintf(temp_log, "%sT", logname); /* Make sure there's no old temp log */ rc = llog_create(lctxt, &local_llh, NULL, temp_log); if (rc) GOTO(out, rc); rc = llog_init_handle(local_llh, LLOG_F_IS_PLAIN, NULL); if (rc) GOTO(out, rc); rc = llog_destroy(local_llh); llog_free_handle(local_llh); if (rc) GOTO(out, rc); /* open local log */ rc = llog_create(lctxt, &local_llh, NULL, temp_log); if (rc) GOTO(out, rc); /* set the log header uuid for fun */ OBD_ALLOC_PTR(uuid); obd_str2uuid(uuid, logname); rc = llog_init_handle(local_llh, LLOG_F_IS_PLAIN, uuid); OBD_FREE_PTR(uuid); if (rc) GOTO(out_closel, rc); /* open remote log */ rc = llog_create(rctxt, &remote_llh, NULL, logname); if (rc) GOTO(out_closel, rc); rc = llog_init_handle(remote_llh, LLOG_F_IS_PLAIN, NULL); if (rc) GOTO(out_closer, rc); /* Copy remote log */ rc = llog_process(remote_llh, mgc_copy_handler,(void *)local_llh, NULL);out_closer: rc2 = llog_close(remote_llh); if (!rc) rc = rc2;out_closel: rc2 = llog_close(local_llh); if (!rc) rc = rc2; /* We've copied the remote log to the local temp log, now replace the old local log with the temp log. */ if (!rc) { struct client_obd *cli = &obd->u.cli; LASSERT(cli); LASSERT(cli->cl_mgc_configs_dir); rc = lustre_rename(cli->cl_mgc_configs_dir, temp_log, logname); } CDEBUG(D_MGC, "Copied remote log %s (%d)\n", logname, rc);out: if (rc) CERROR("Failed to copy remote log %s (%d)\n", logname, rc); OBD_FREE(temp_log, strlen(logname) + 1); RETURN(rc);}DECLARE_MUTEX(llog_process_lock);/* Get a config log from the MGS and process it. This func is called for both clients and servers. */static int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld){ struct llog_ctxt *ctxt, *lctxt; struct lustre_handle lockh; struct client_obd *cli = &mgc->u.cli; struct lvfs_run_ctxt saved; struct lustre_sb_info *lsi; int rc = 0, rcl, flags = 0, must_pop = 0; ENTRY; if (!cld || !cld->cld_cfg.cfg_sb) { /* This should never happen */ CERROR("Missing cld, aborting log update\n"); RETURN(-EINVAL); } if (cld->cld_stopping) RETURN(0); OBD_FAIL_TIMEOUT(OBD_FAIL_MGC_PAUSE_PROCESS_LOG, 20); lsi = s2lsi(cld->cld_cfg.cfg_sb); CDEBUG(D_MGC, "Process log %s:%s from %d\n", cld->cld_logname, cld->cld_cfg.cfg_instance, cld->cld_cfg.cfg_last_idx + 1); ctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT); if (!ctxt) { CERROR("missing llog context\n"); RETURN(-EINVAL); } /* I don't want mutliple processes running process_log at once -- sounds like badness. It actually might be fine, as long as we're not trying to update from the same log simultaneously (in which case we should use a per-log sem.) */ down(&llog_process_lock); /* Get the cfg lock on the llog */ rcl = mgc_enqueue(mgc->u.cli.cl_mgc_mgsexp, NULL, LDLM_PLAIN, NULL, LCK_CR, &flags, NULL, NULL, NULL, cld, 0, NULL, &lockh); if (rcl) CDEBUG(D_MGC, "Can't get cfg lock: %d\n", rcl); lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT); /* Copy the setup log locally if we can. Don't mess around if we're running an MGS though (logs are already local). */ if (lctxt && lsi && (lsi->lsi_flags & LSI_SERVER) && (lsi->lsi_srv_mnt == cli->cl_mgc_vfsmnt) && !IS_MGS(lsi->lsi_ldd)) { push_ctxt(&saved, &mgc->obd_lvfs_ctxt, NULL); must_pop++; if (rcl == 0) /* Only try to copy log if we have the lock. */ rc = mgc_copy_llog(mgc, ctxt, lctxt, cld->cld_logname); if (rcl || rc) { if (mgc_llog_is_empty(mgc, lctxt, cld->cld_logname)) { LCONSOLE_ERROR_MSG(0x13a, "Failed to get MGS " "log %s and no local copy." "\n", cld->cld_logname); GOTO(out_pop, rc = -ENOTCONN); } CDEBUG(D_MGC, "Failed to get MGS log %s, using local " "copy for now, will try to update later.\n", cld->cld_logname); } /* Now, whether we copied or not, start using the local llog. If we failed to copy, we'll start using whatever the old log has. */ llog_ctxt_put(ctxt); ctxt = lctxt; } /* logname and instance info should be the same, so use our copy of the instance for the update. The cfg_last_idx will be updated here. */ rc = class_config_parse_llog(ctxt, cld->cld_logname, &cld->cld_cfg); out_pop: llog_ctxt_put(ctxt); if (ctxt != lctxt) llog_ctxt_put(lctxt); if (must_pop) pop_ctxt(&saved, &mgc->obd_lvfs_ctxt, NULL); /* Now drop the lock so MGS can revoke it */ if (!rcl) { rcl = mgc_cancel(mgc->u.cli.cl_mgc_mgsexp, NULL, LCK_CR, &lockh); if (rcl) CERROR("Can't drop cfg lock: %d\n", rcl); } CDEBUG(D_MGC, "%s: configuration from log '%s' %sed (%d).\n", mgc->obd_name, cld->cld_logname, rc ? "fail" : "succeed", rc); up(&llog_process_lock); RETURN(rc);}static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf){ struct lustre_cfg *lcfg = buf; int cmd; int rc = 0; ENTRY; switch(cmd = lcfg->lcfg_command) { case LCFG_LOV_ADD_OBD: { /* Add any new target, not just osts */ struct mgs_target_info *mti; if (LUSTRE_CFG_BUFLEN(lcfg, 1) != sizeof(struct mgs_target_info)) GOTO(out, rc = -EINVAL); mti = (struct mgs_target_info *)lustre_cfg_buf(lcfg, 1); CDEBUG(D_MGC, "add_target %s %#x\n", mti->mti_svname, mti->mti_flags); rc = mgc_target_register(obd->u.cli.cl_mgc_mgsexp, mti); break; } case LCFG_LOV_DEL_OBD: /* Remove target from the fs? */ /* FIXME */ CERROR("lov_del_obd unimplemented\n"); rc = -ENOSYS; break; case LCFG_LOG_START: { struct config_llog_data *cld; struct config_llog_instance *cfg; struct super_block *sb; char *logname = lustre_cfg_string(lcfg, 1); cfg = (struct config_llog_instance *)lustre_cfg_buf(lcfg, 2); sb = *(struct super_block **)lustre_cfg_buf(lcfg, 3); CDEBUG(D_MGC, "parse_log %s from %d\n", logname, cfg->cfg_last_idx); /* We're only called through here on the initial mount */ rc = config_log_add(logname, cfg, sb); if (rc) break; cld = config_log_find(logname, cfg); if (IS_ERR(cld)) { rc = PTR_ERR(cld); break; } /* COMPAT_146 */ /* FIXME only set this for old logs! Right now this forces us to always skip the "inside markers" check */ cld->cld_cfg.cfg_flags |= CFG_F_COMPAT146; rc = mgc_process_log(obd, cld); config_log_put(cld); break; } case LCFG_LOG_END: { struct config_llog_instance *cfg = NULL; char *logname = lustre_cfg_string(lcfg, 1); if (lcfg->lcfg_bufcount >= 2) cfg = (struct config_llog_instance *)lustre_cfg_buf( lcfg, 2); rc = config_log_end(logname, cfg); break; } default: { CERROR("Unknown command: %d\n", lcfg->lcfg_command); GOTO(out, rc = -EINVAL); } }out: RETURN(rc);}struct obd_ops mgc_obd_ops = { .o_owner = THIS_MODULE, .o_setup = mgc_setup, .o_precleanup = mgc_precleanup, .o_cleanup = mgc_cleanup, .o_add_conn = client_import_add_conn, .o_del_conn = client_import_del_conn, .o_connect = client_connect_import, .o_disconnect = client_disconnect_export, //.o_enqueue = mgc_enqueue, .o_cancel = mgc_cancel, //.o_iocontrol = mgc_iocontrol, .o_set_info_async = mgc_set_info_async, .o_import_event = mgc_import_event, .o_llog_init = mgc_llog_init, .o_llog_finish = mgc_llog_finish, .o_process_config = mgc_process_config,};int __init mgc_init(void){ return class_register_type(&mgc_obd_ops, NULL, LUSTRE_MGC_NAME);}#ifdef __KERNEL__static void /*__exit*/ mgc_exit(void){ class_unregister_type(LUSTRE_MGC_NAME);}MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");MODULE_DESCRIPTION("Lustre Management Client");MODULE_LICENSE("GPL");module_init(mgc_init);module_exit(mgc_exit);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -