X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmgc%2Fmgc_request.c;h=dab90012cd47c8a3c46407aeef0f780d48e6cd8d;hb=b2f4fd040713bea3ad3d3f2540048c0ee8e07def;hp=36a578bd894f0cced07c1cc235c8cca8a5aae434;hpb=492125c2d1e3e77c5c2ec31e888ce3eb070f2120;p=fs%2Flustre-release.git diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 36a578b..dab9001 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -23,7 +23,7 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ - + #ifndef EXPORT_SYMTAB # define EXPORT_SYMTAB #endif @@ -41,45 +41,58 @@ #include #include +#include #include #include #include +#include "mgc_internal.h" - -int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id) +static int mgc_name2resid(char *name, int len, struct ldlm_res_id *res_id) { - char *name_end; - int len; __u64 resname = 0; - - /* fsname is at most 8 chars long at the beginning of the logname - e.g. "lustre-MDT0001" or "lustre" */ - name_end = strrchr(logname, '-'); - if (name_end) - len = name_end - logname; - else - len = strlen(logname); + if (len > 8) { - CERROR("fsname too long: %s\n", logname); + CERROR("name too long: %s\n", name); return -EINVAL; } if (len <= 0) { - CERROR("missing fsname: %s\n", logname); + CERROR("missing name: %s\n", name); return -EINVAL; } - memcpy(&resname, logname, len); + memcpy(&resname, name, len); memset(res_id, 0, sizeof(*res_id)); + /* Always use the same endianness for the resid */ res_id->name[0] = cpu_to_le64(resname); - CDEBUG(D_MGC, "log %s to resid "LPX64"/"LPX64" (%.8s)\n", logname, + CDEBUG(D_MGC, "log %s to resid "LPX64"/"LPX64" (%.8s)\n", name, res_id->name[0], res_id->name[1], (char *)&res_id->name[0]); return 0; } -EXPORT_SYMBOL(mgc_logname2resid); + +int mgc_fsname2resid(char *fsname, struct ldlm_res_id *res_id) +{ + /* fsname is at most 8 chars long, maybe contain "-". + * e.g. "lustre", "CFS-000" */ + return mgc_name2resid(fsname, strlen(fsname), res_id); +} +EXPORT_SYMBOL(mgc_fsname2resid); + +int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id) +{ + char *name_end; + int len; + + /* logname consists of "fsname-nodetype". + * e.g. "lustre-MDT0001", "CFS-000-client" */ + name_end = strrchr(logname, '-'); + LASSERT(name_end); + len = name_end - logname; + return mgc_name2resid(logname, len, res_id); +} /********************** config llog list **********************/ -static struct list_head config_llog_list = LIST_HEAD_INIT(config_llog_list); +static CFS_LIST_HEAD(config_llog_list); static spinlock_t config_list_lock = SPIN_LOCK_UNLOCKED; /* Take a reference to a config log */ @@ -94,7 +107,7 @@ static int config_log_get(struct config_llog_data *cld) RETURN(0); } -/* Drop a reference to a config log. When no longer referenced, +/* Drop a reference to a config log. When no longer referenced, we can free the config log data */ static void config_log_put(struct config_llog_data *cld) { @@ -109,7 +122,7 @@ static void config_log_put(struct config_llog_data *cld) spin_unlock(&config_list_lock); OBD_FREE(cld->cld_logname, strlen(cld->cld_logname) + 1); if (cld->cld_cfg.cfg_instance != NULL) - OBD_FREE(cld->cld_cfg.cfg_instance, + OBD_FREE(cld->cld_cfg.cfg_instance, strlen(cld->cld_cfg.cfg_instance) + 1); OBD_FREE(cld, sizeof(*cld)); } @@ -117,8 +130,8 @@ static void config_log_put(struct config_llog_data *cld) } /* Find a config log by name */ -static struct config_llog_data *config_log_find(char *logname, - struct config_llog_instance *cfg) +static struct config_llog_data *config_log_find(char *logname, + struct config_llog_instance *cfg) { struct list_head *tmp; struct config_llog_data *cld; @@ -138,16 +151,16 @@ static struct config_llog_data *config_log_find(char *logname, spin_lock(&config_list_lock); list_for_each(tmp, &config_llog_list) { cld = list_entry(tmp, struct config_llog_data, cld_list_chain); - if (match_instance && cld->cld_cfg.cfg_instance && + if (match_instance && cld->cld_cfg.cfg_instance && strcmp(logid, cld->cld_cfg.cfg_instance) == 0) goto out_found; - if (!match_instance && + if (!match_instance && strcmp(logid, cld->cld_logname) == 0) goto out_found; } spin_unlock(&config_list_lock); - CERROR("can't get log %s\n", logid); + CDEBUG(D_CONFIG, "can't get log %s\n", logid); RETURN(ERR_PTR(-ENOENT)); out_found: atomic_inc(&cld->cld_refcount); @@ -155,7 +168,7 @@ out_found: RETURN(cld); } -/* Add this log to our list of active logs. +/* Add this log to our list of active logs. We have one active log per "mount" - client instance or servername. Each instance may be at a different point in the log. */ static int config_log_add(char *logname, struct config_llog_instance *cfg, @@ -167,12 +180,12 @@ static int config_log_add(char *logname, struct config_llog_instance *cfg, ENTRY; CDEBUG(D_MGC, "adding config log %s:%s\n", logname, cfg->cfg_instance); - + OBD_ALLOC(cld, sizeof(*cld)); - if (!cld) + if (!cld) RETURN(-ENOMEM); OBD_ALLOC(cld->cld_logname, strlen(logname) + 1); - if (!cld->cld_logname) { + if (!cld->cld_logname) { OBD_FREE(cld, sizeof(*cld)); RETURN(-ENOMEM); } @@ -182,12 +195,12 @@ static int config_log_add(char *logname, struct config_llog_instance *cfg, cld->cld_cfg.cfg_flags = 0; cld->cld_cfg.cfg_sb = sb; atomic_set(&cld->cld_refcount, 1); - + /* Keep the mgc around until we are done */ cld->cld_mgcexp = class_export_get(lsi->lsi_mgc->obd_self_export); - + if (cfg->cfg_instance != NULL) { - OBD_ALLOC(cld->cld_cfg.cfg_instance, + OBD_ALLOC(cld->cld_cfg.cfg_instance, strlen(cfg->cfg_instance) + 1); strcpy(cld->cld_cfg.cfg_instance, cfg->cfg_instance); } @@ -200,19 +213,19 @@ static int config_log_add(char *logname, struct config_llog_instance *cfg, config_log_put(cld); RETURN(rc); } - + RETURN(rc); } /* Stop watching for updates on this log. */ static int config_log_end(char *logname, struct config_llog_instance *cfg) -{ +{ struct config_llog_data *cld; int rc = 0; ENTRY; - + cld = config_log_find(logname, cfg); - if (IS_ERR(cld)) + if (IS_ERR(cld)) RETURN(PTR_ERR(cld)); /* drop the ref from the find */ config_log_put(cld); @@ -235,6 +248,7 @@ static cfs_waitq_t rq_waitq; static int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld); +static int mgc_requeue_add(struct config_llog_data *cld, int later); static int mgc_requeue_thread(void *data) { @@ -243,7 +257,7 @@ static int mgc_requeue_thread(void *data) char name[] = "ll_cfg_requeue"; int rc = 0; ENTRY; - + ptlrpc_daemonize(name); CDEBUG(D_MGC, "Starting requeue thread\n"); @@ -268,8 +282,7 @@ static int mgc_requeue_thread(void *data) spin_lock(&config_list_lock); list_for_each_entry_safe(cld, n, &config_llog_list, cld_list_chain) { - spin_unlock(&config_list_lock); - + spin_unlock(&config_list_lock); if (cld->cld_lostlock) { CDEBUG(D_MGC, "updating log %s\n", cld->cld_logname); @@ -278,10 +291,9 @@ static int mgc_requeue_thread(void *data) cld); /* Whether we enqueued again or not in mgc_process_log, we're done with the ref - from the old enqueue */ + from the old enqueue */ config_log_put(cld); } - spin_lock(&config_list_lock); } spin_unlock(&config_list_lock); @@ -308,7 +320,7 @@ static int mgc_requeue_add(struct config_llog_data *cld, int later) CDEBUG(D_INFO, "log %s: requeue (l=%d r=%d sp=%d st=%x)\n", cld->cld_logname, later, atomic_read(&cld->cld_refcount), cld->cld_stopping, rq_state); - + /* Hold lock for rq_state */ spin_lock(&config_list_lock); cld->cld_lostlock = 1; @@ -345,7 +357,7 @@ static int mgc_requeue_add(struct config_llog_data *cld, int later) /********************** class fns **********************/ -static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, +static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, struct vfsmount *mnt) { struct lvfs_run_ctxt saved; @@ -367,7 +379,7 @@ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, obd->obd_fsops = fsfilt_get_ops(MT_STR(lsi->lsi_ldd)); if (IS_ERR(obd->obd_fsops)) { up(&cli->cl_mgc_sem); - CERROR("No fstype %s rc=%ld\n", MT_STR(lsi->lsi_ldd), + CERROR("No fstype %s rc=%ld\n", MT_STR(lsi->lsi_ldd), PTR_ERR(obd->obd_fsops)); RETURN(PTR_ERR(obd->obd_fsops)); } @@ -386,7 +398,7 @@ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); - CERROR("cannot lookup %s directory: rc = %d\n", + CERROR("cannot lookup %s directory: rc = %d\n", MOUNT_CONFIGS_DIR, err); GOTO(err_ops, err); } @@ -403,7 +415,7 @@ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, /* We keep the cl_mgc_sem until mgc_fs_cleanup */ RETURN(0); -err_ops: +err_ops: fsfilt_put_ops(obd->obd_fsops); obd->obd_fsops = NULL; cli->cl_mgc_vfsmnt = NULL; @@ -423,15 +435,15 @@ static int mgc_fs_cleanup(struct obd_device *obd) struct lvfs_run_ctxt saved; push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); l_dput(cli->cl_mgc_configs_dir); - cli->cl_mgc_configs_dir = NULL; + cli->cl_mgc_configs_dir = NULL; pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); class_decref(obd); } cli->cl_mgc_vfsmnt = NULL; - if (obd->obd_fsops) + if (obd->obd_fsops) fsfilt_put_ops(obd->obd_fsops); - + up(&cli->cl_mgc_sem); RETURN(rc); @@ -444,7 +456,7 @@ static int mgc_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage) ENTRY; switch (stage) { - case OBD_CLEANUP_EARLY: + case OBD_CLEANUP_EARLY: break; case OBD_CLEANUP_EXPORTS: if (atomic_dec_and_test(&mgc_count)) { @@ -474,36 +486,41 @@ static int mgc_cleanup(struct obd_device *obd) ENTRY; LASSERT(cli->cl_mgc_vfsmnt == NULL); - - /* COMPAT_146 - old config logs may have added profiles we don't + + /* COMPAT_146 - old config logs may have added profiles we don't know about */ - if (obd->obd_type->typ_refcnt <= 1) + if (obd->obd_type->typ_refcnt <= 1) /* Only for the last mgc */ class_del_profiles(); + lprocfs_obd_cleanup(obd); ptlrpcd_decref(); rc = client_obd_cleanup(obd); RETURN(rc); } -static int mgc_setup(struct obd_device *obd, obd_count len, void *buf) +static int mgc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) { + struct lprocfs_static_vars lvars; int rc; ENTRY; ptlrpcd_addref(); - rc = client_obd_setup(obd, len, buf); + rc = client_obd_setup(obd, lcfg); if (rc) GOTO(err_decref, rc); - rc = obd_llog_init(obd, obd, 0, NULL, NULL); + rc = obd_llog_init(obd, OBD_LLOG_GROUP, obd, 0, NULL, NULL); if (rc) { CERROR("failed to setup llogging subsystems\n"); GOTO(err_cleanup, rc); } + lprocfs_mgc_init_vars(&lvars); + lprocfs_obd_setup(obd, lvars.obd_vars); + spin_lock(&config_list_lock); atomic_inc(&mgc_count); if (atomic_read(&mgc_count) == 1) { @@ -540,11 +557,11 @@ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, case LDLM_CB_CANCELING: { /* We've given up the lock, prepare ourselves to update. */ LDLM_DEBUG(lock, "MGC cancel CB"); - + CDEBUG(D_MGC, "Lock res "LPX64" (%.8s)\n", - lock->l_resource->lr_name.name[0], + lock->l_resource->lr_name.name[0], (char *)&lock->l_resource->lr_name.name[0]); - + if (!cld) { CERROR("missing data, won't requeue\n"); break; @@ -583,27 +600,64 @@ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, if (rc) { - CERROR("%s CB failed %d:\n", flag == LDLM_CB_BLOCKING ? + CERROR("%s CB failed %d:\n", flag == LDLM_CB_BLOCKING ? "blocking" : "cancel", rc); LDLM_ERROR(lock, "MGC ast"); } RETURN(rc); } +/* Send parameter to MGS*/ +static int mgc_set_mgs_param(struct obd_export *exp, + struct mgs_send_param *msp) +{ + struct ptlrpc_request *req; + struct mgs_send_param *req_msp, *rep_msp; + int size[] = { sizeof(struct ptlrpc_body), sizeof(*req_msp) }; + int rep_size[] = { sizeof(struct ptlrpc_body), sizeof(*msp) }; + int rc; + ENTRY; + + req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MGS_VERSION, + MGS_SET_INFO, 2, size, NULL); + if (!req) + RETURN(-ENOMEM); + + req_msp = lustre_msg_buf(req->rq_reqmsg, REQ_REC_OFF, sizeof(*req_msp)); + if (!req_msp) + RETURN(-ENOMEM); + + memcpy(req_msp, msp, sizeof(*req_msp)); + ptlrpc_req_set_repsize(req, 2, rep_size); + rc = ptlrpc_queue_wait(req); + if (!rc) { + rep_msp = lustre_swab_repbuf(req, REPLY_REC_OFF, + sizeof(*rep_msp), NULL); + memcpy(msp, rep_msp, sizeof(*rep_msp)); + } + + ptlrpc_req_finished(req); + + RETURN(rc); +} + /* Take a config lock so we can get cancel notifications */ static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm, __u32 type, ldlm_policy_data_t *policy, __u32 mode, int *flags, void *bl_cb, void *cp_cb, void *gl_cb, void *data, __u32 lvb_len, void *lvb_swabber, struct lustre_handle *lockh) -{ +{ struct config_llog_data *cld = (struct config_llog_data *)data; + struct ldlm_enqueue_info einfo = { type, mode, mgc_blocking_ast, + ldlm_completion_ast, NULL, data}; + int rc; ENTRY; CDEBUG(D_MGC, "Enqueue for %s (res "LPX64")\n", cld->cld_logname, cld->cld_resid.name[0]); - + /* We can only drop this config log ref when we drop the lock */ if (config_log_get(cld)) RETURN(ELDLM_LOCK_ABORTED); @@ -611,10 +665,8 @@ static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm, /* We need a callback for every lockholder, so don't try to ldlm_lock_match (see rev 1.1.2.11.2.47) */ - rc = ldlm_cli_enqueue(exp, NULL, cld->cld_resid, - type, NULL, mode, flags, - mgc_blocking_ast, ldlm_completion_ast, NULL, - data, NULL, 0, NULL, lockh, 0); + rc = ldlm_cli_enqueue(exp, NULL, &einfo, &cld->cld_resid, + NULL, flags, NULL, 0, NULL, lockh, 0); /* A failed enqueue should still call the mgc_blocking_ast, where it will be requeued if needed ("grant failed"). */ @@ -642,14 +694,10 @@ static int mgc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, int rc; ENTRY; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - MOD_INC_USE_COUNT; -#else if (!try_module_get(THIS_MODULE)) { CERROR("Can't get module. Is it alive?"); return -EINVAL; } -#endif switch (cmd) { /* REPLicator context */ case OBD_IOC_PARSE: { @@ -683,11 +731,7 @@ static int mgc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, GOTO(out, rc = -ENOTTY); } out: -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - MOD_DEC_USE_COUNT; -#else module_put(THIS_MODULE); -#endif return rc; } @@ -697,32 +741,28 @@ out: static int mgc_target_register(struct obd_export *exp, struct mgs_target_info *mti) { - struct ptlrpc_request *req; + struct ptlrpc_request *req; struct mgs_target_info *req_mti, *rep_mti; - int size[] = { sizeof(struct ptlrpc_body), sizeof(*req_mti) }; - int rep_size[] = { sizeof(struct ptlrpc_body), sizeof(*mti) }; - int rc; + int rc; ENTRY; - req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MGS_VERSION, - MGS_TARGET_REG, 2, size, NULL); - if (!req) + req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), + &RQF_MGS_TARGET_REG, LUSTRE_MGS_VERSION, + MGS_TARGET_REG); + if (req == NULL) RETURN(-ENOMEM); - req_mti = lustre_msg_buf(req->rq_reqmsg, REQ_REC_OFF, sizeof(*req_mti)); - if (!req_mti) - RETURN(-ENOMEM); + req_mti = req_capsule_client_get(&req->rq_pill, &RMF_MGS_TARGET_INFO); memcpy(req_mti, mti, sizeof(*req_mti)); - ptlrpc_req_set_repsize(req, 2, rep_size); + ptlrpc_request_set_replen(req); CDEBUG(D_MGC, "register %s\n", mti->mti_svname); - + rc = ptlrpc_queue_wait(req); if (!rc) { - rep_mti = lustre_swab_repbuf(req, REPLY_REC_OFF, - sizeof(*rep_mti), - lustre_swab_mgs_target_info); + rep_mti = req_capsule_server_get(&req->rq_pill, + &RMF_MGS_TARGET_INFO); memcpy(mti, rep_mti, sizeof(*rep_mti)); CDEBUG(D_MGC, "register %s got index = %d\n", mti->mti_svname, mti->mti_stripe_index); @@ -733,7 +773,7 @@ static int mgc_target_register(struct obd_export *exp, } int mgc_set_info_async(struct obd_export *exp, obd_count keylen, - void *key, obd_count vallen, void *val, + void *key, obd_count vallen, void *val, struct ptlrpc_request_set *set) { struct obd_import *imp = class_exp2cliimp(exp); @@ -744,7 +784,9 @@ int mgc_set_info_async(struct obd_export *exp, obd_count keylen, if (KEY_IS(KEY_INIT_RECOV)) { if (vallen != sizeof(int)) RETURN(-EINVAL); + spin_lock(&imp->imp_lock); imp->imp_initial_recov = *(int *)val; + spin_unlock(&imp->imp_lock); CDEBUG(D_HA, "%s: set imp_initial_recov = %d\n", exp->exp_obd->obd_name, imp->imp_initial_recov); RETURN(0); @@ -755,30 +797,20 @@ int mgc_set_info_async(struct obd_export *exp, obd_count keylen, if (vallen != sizeof(int)) RETURN(-EINVAL); value = *(int *)val; + spin_lock(&imp->imp_lock); imp->imp_initial_recov_bk = value > 0; - /* Even after the initial connection, give up all comms if + /* Even after the initial connection, give up all comms if nobody answers the first time. */ imp->imp_recon_bk = 1; - CDEBUG(D_MGC, "InitRecov %s %d/%d:d%d:i%d:r%d:or%d:%s\n", + spin_unlock(&imp->imp_lock); + CDEBUG(D_MGC, "InitRecov %s %d/%d:d%d:i%d:r%d:or%d:%s\n", imp->imp_obd->obd_name, value, imp->imp_initial_recov, - imp->imp_deactive, imp->imp_invalid, + imp->imp_deactive, imp->imp_invalid, imp->imp_replayable, imp->imp_obd->obd_replayable, ptlrpc_import_state_name(imp->imp_state)); /* Resurrect if we previously died */ - if (imp->imp_invalid || value > 1) { - /* See client_disconnect_export */ - /* Allow reconnect attempts */ - imp->imp_obd->obd_no_recov = 0; - /* Force a new connect attempt */ - /* (can't put these in obdclass, module loop) */ - ptlrpc_invalidate_import(imp); - /* Do a fresh connect next time by zeroing the handle */ - ptlrpc_disconnect_import(imp, 1); - /* Remove 'invalid' flag */ - ptlrpc_activate_import(imp); - /* Attempt a new connect */ - ptlrpc_recover_import(imp, NULL); - } + if (imp->imp_invalid || value > 1) + ptlrpc_reconnect_import(imp); RETURN(0); } /* FIXME move this to mgc_process_config */ @@ -813,9 +845,16 @@ int mgc_set_info_async(struct obd_export *exp, obd_count keylen, } 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, @@ -827,19 +866,20 @@ static int mgc_import_event(struct obd_device *obd, CDEBUG(D_MGC, "import event %#x\n", event); switch (event) { - case IMP_EVENT_DISCON: + case IMP_EVENT_DISCON: /* MGC imports should not wait for recovery */ - ptlrpc_invalidate_import(imp); break; - case IMP_EVENT_INACTIVE: + 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: + 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; @@ -850,24 +890,29 @@ static int mgc_import_event(struct obd_device *obd, 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) +static int mgc_llog_init(struct obd_device *obd, int group, + struct obd_device *tgt, int count, + struct llog_catid *logid, struct obd_uuid *uuid) { struct llog_ctxt *ctxt; + struct obd_llog_group *olg = &obd->obd_olg; int rc; ENTRY; - rc = llog_setup(obd, LLOG_CONFIG_ORIG_CTXT, tgt, 0, NULL, + LASSERT(group == OBD_LLOG_GROUP); + LASSERT(olg->olg_group == group); + + rc = llog_setup(obd, olg, 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, + rc = llog_setup(obd, olg, 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_initiator_connect(ctxt); + llog_ctxt_put(ctxt); } RETURN(rc); @@ -875,11 +920,20 @@ static int mgc_llog_init(struct obd_device *obd, struct obd_device *tgt, static int mgc_llog_finish(struct obd_device *obd, int count) { - int rc; + struct llog_ctxt *ctxt; + int rc = 0, rc2 = 0; ENTRY; - rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_REPL_CTXT)); - rc = llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT)); + ctxt = llog_get_context(obd, LLOG_CONFIG_REPL_CTXT); + if (ctxt) + rc = llog_cleanup(ctxt); + + ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); + if (ctxt) + rc2 = llog_cleanup(ctxt); + + if (!rc) + rc = rc2; RETURN(rc); } @@ -904,7 +958,7 @@ static int mgc_llog_is_empty(struct obd_device *obd, struct llog_ctxt *ctxt, return(rc <= 1); } -static int mgc_copy_handler(struct llog_handle *llh, struct llog_rec_hdr *rec, +static int mgc_copy_handler(struct llog_handle *llh, struct llog_rec_hdr *rec, void *data) { struct llog_rec_hdr local_rec = *rec; @@ -916,12 +970,12 @@ static int mgc_copy_handler(struct llog_handle *llh, struct llog_rec_hdr *rec, /* Append all records */ local_rec.lrh_len -= sizeof(*rec) + sizeof(struct llog_rec_tail); - rc = llog_write_rec(local_llh, &local_rec, NULL, 0, + 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, + 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); @@ -1010,7 +1064,7 @@ 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, +static int mgc_process_log(struct obd_device *mgc, struct config_llog_data *cld) { struct llog_ctxt *ctxt, *lctxt; @@ -1026,19 +1080,14 @@ static int mgc_process_log(struct obd_device *mgc, CERROR("Missing cld, aborting log update\n"); RETURN(-EINVAL); } - if (cld->cld_stopping) - RETURN(0); - - if (cld->cld_cfg.cfg_flags & CFG_F_SERVER146) - /* If we started from an old MDT, don't bother trying to - get log updates from the MGS */ + if (cld->cld_stopping) RETURN(0); OBD_FAIL_TIMEOUT(OBD_FAIL_MGC_PROCESS_LOG, 20); lsi = s2lsi(cld->cld_cfg.cfg_sb); - CDEBUG(D_MGC, "Process log %s:%s from %d\n", cld->cld_logname, + 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); @@ -1047,69 +1096,73 @@ static int mgc_process_log(struct obd_device *mgc, RETURN(-EINVAL); } - /* I don't want mutliple processes running process_log at once -- - sounds like badness. It actually might be fine, as long as + /* 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, + 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) + 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 + /* 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) && + 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) + 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("Failed to get MGS log %s " - "and no local copy.\n", - 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); } - LCONSOLE_WARN("Failed to get MGS log %s, using " - "local copy.\n", cld->cld_logname); + 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 + 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 + /* 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: - if (must_pop) +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 */ + /* Now drop the lock so MGS can revoke it */ if (!rcl) { - rcl = mgc_cancel(mgc->u.cli.cl_mgc_mgsexp, NULL, + rcl = mgc_cancel(mgc->u.cli.cl_mgc_mgsexp, NULL, LCK_CR, &lockh); - if (rcl) + 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); } @@ -1125,18 +1178,18 @@ static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf) /* Add any new target, not just osts */ struct mgs_target_info *mti; - if (LUSTRE_CFG_BUFLEN(lcfg, 1) != + 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", + 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? */ + /* Remove target from the fs? */ /* FIXME */ CERROR("lov_del_obd unimplemented\n"); rc = -ENOSYS; @@ -1148,29 +1201,29 @@ static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf) 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, + + 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) + 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; + + break; } case LCFG_LOG_END: { struct config_llog_instance *cfg = NULL; @@ -1212,7 +1265,8 @@ struct obd_ops mgc_obd_ops = { int __init mgc_init(void) { - return class_register_type(&mgc_obd_ops, NULL, LUSTRE_MGC_NAME); + return class_register_type(&mgc_obd_ops, NULL, NULL, + LUSTRE_MGC_NAME, NULL); } #ifdef __KERNEL__