From f921c2af24f4a42b7cea26f8f8441e6c0d457fe6 Mon Sep 17 00:00:00 2001 From: nathan Date: Wed, 4 Jan 2006 20:32:04 +0000 Subject: [PATCH] Branch b1_4_mountconf b=8192 config log updates working (continue parsing log from last step (per instance) when server cancels config lock) --- lustre/include/linux/lustre_cfg.h | 3 +- lustre/include/linux/lustre_disk.h | 9 +- lustre/include/linux/lustre_log.h | 8 - lustre/include/linux/obd_class.h | 8 + lustre/llite/llite_lib.c | 6 +- lustre/lov/lov_obd.c | 4 +- lustre/mgc/mgc_request.c | 331 +++++++++++++++++++++++++++---------- lustre/obdclass/llog.c | 4 +- lustre/obdclass/obd_config.c | 2 +- lustre/obdclass/obd_mount.c | 147 ++++------------ 10 files changed, 302 insertions(+), 220 deletions(-) diff --git a/lustre/include/linux/lustre_cfg.h b/lustre/include/linux/lustre_cfg.h index d6bb24a..71ec87e 100644 --- a/lustre/include/linux/lustre_cfg.h +++ b/lustre/include/linux/lustre_cfg.h @@ -51,7 +51,8 @@ enum lcfg_command_type { LCFG_LOV_DEL_OBD = 0x00cf00e, LCFG_PARAM = 0x00cf00f, LCFG_MARKER = 0x00cf010, - LCFG_PARSE_LOG = 0x00cf011, + LCFG_LOG_START = 0x00cf011, + LCFG_LOG_END = 0x00cf012, }; struct lustre_cfg_bufs { diff --git a/lustre/include/linux/lustre_disk.h b/lustre/include/linux/lustre_disk.h index 4d9dcb3..5e2d051 100644 --- a/lustre/include/linux/lustre_disk.h +++ b/lustre/include/linux/lustre_disk.h @@ -232,13 +232,12 @@ struct lustre_mount_info { /* obd_mount.c */ void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb)); int lustre_common_put_super(struct super_block *sb); +int lustre_process_log(struct super_block *sb, char *logname, + struct config_llog_instance *cfg); +int lustre_end_log(struct super_block *sb, char *logname, + struct config_llog_instance *cfg); struct lustre_mount_info *server_get_mount(char *name); int server_put_mount(char *name, struct vfsmount *mnt); -int config_log_start(struct super_block *, char *, - struct config_llog_instance *cfg); -int config_log_end(char *instance); -struct config_llog_data *config_log_get(char *name); -void config_log_put(void); /* mgc_request.c */ int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id); diff --git a/lustre/include/linux/lustre_log.h b/lustre/include/linux/lustre_log.h index 52ad5c1..09e7d83 100644 --- a/lustre/include/linux/lustre_log.h +++ b/lustre/include/linux/lustre_log.h @@ -107,14 +107,6 @@ int llog_cat_cancel_records(struct llog_handle *cathandle, int count, int llog_cat_process(struct llog_handle *cat_llh, llog_cb_t cb, void *data); int llog_cat_set_first_idx(struct llog_handle *cathandle, int index); -/* list of configuration llogs we are watching */ -struct config_llog_data { - char *cld_name; - __u32 cld_gen; - struct ldlm_res_id cld_res_id; - struct list_head cld_list_chain; -}; - /* llog_obd.c */ int llog_setup(struct obd_device *obd, int index, struct obd_device *disk_obd, int count, struct llog_logid *logid,struct llog_operations *op); diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 078ee34..87fdd4c 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -115,6 +115,14 @@ int class_config_parse_llog(struct llog_ctxt *ctxt, char *name, int class_config_dump_llog(struct llog_ctxt *ctxt, char *name, struct config_llog_instance *cfg); +/* list of active configuration logs */ +struct config_llog_data { + char *cld_logname; + struct ldlm_res_id cld_resid; + struct config_llog_instance cld_cfg; + struct list_head cld_list_chain; +}; + struct lustre_profile { struct list_head lp_list; char * lp_profile; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index ec64ca6..4ff505c 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -521,7 +521,7 @@ int ll_fill_super(struct super_block *sb) cfg.cfg_uuid = lsi->lsi_llsbi->ll_sb_uuid; /* set up client obds */ - err = config_log_start(sb, profilenm, &cfg); + err = lustre_process_log(sb, profilenm, &cfg); if (err < 0) { CERROR("Unable to process log: %d\n", err); GOTO(out_free, err); @@ -573,6 +573,7 @@ out_free: void ll_put_super(struct super_block *sb) { + struct config_llog_instance cfg; char ll_instance[sizeof(sb) * 2 + 1]; struct obd_device *obd; struct lustre_sb_info *lsi = s2lsi(sb); @@ -584,7 +585,8 @@ void ll_put_super(struct super_block *sb) CDEBUG(D_VFSTRACE, "VFS Op: sb %p - %s\n", sb, profilenm); sprintf(ll_instance, "%p", sb); - config_log_end(ll_instance); + cfg.cfg_instance = ll_instance; + lustre_end_log(sb, NULL, &cfg); obd = class_exp2obd(sbi->ll_mdc_exp); if (obd) { diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 05f8c93..0d7d5be 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -262,8 +262,8 @@ static int lov_disconnect_obd(struct obd_device *obd, struct lov_tgt_desc *tgt) int rc; ENTRY; - CDEBUG(D_CONFIG, "Disconnecting target %s from %s\n", - osc_obd->obd_name, obd->obd_name); + CDEBUG(D_CONFIG, "%s: disconnecting target %s\n", + obd->obd_name, osc_obd->obd_name); lov_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds"); if (lov_proc_dir) { diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 637186d..c755c6d 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -49,6 +49,149 @@ #include "mgc_internal.h" + +int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id) +{ + char *name_end; + + /* fsname is at most 8 chars long at the beginning of the logname + e.g. "lustre-MDT0001" or "lustre" */ + name_end = strchr(logname, '-'); + if (!name_end) + name_end = logname + strlen(logname); + LASSERT(name_end - logname <= 8); + + memcpy(&res_id->name[0], logname, name_end - logname); + CDEBUG(D_MGC, "log %s to resid "LPX64"\n", logname, res_id->name[0]); + return 0; +} +EXPORT_SYMBOL(mgc_logname2resid); + +/********************** config llog list **********************/ +DECLARE_MUTEX(config_llog_lock); +struct list_head config_llog_list = LIST_HEAD_INIT(config_llog_list); + +/* Find log and take the global log sem. 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.) */ +static struct config_llog_data *config_log_get(char *logname, + struct config_llog_instance *cfg) +{ + struct list_head *tmp; + struct config_llog_data *cld; + int match_instance = 0; + + if (cfg) { + CDEBUG(D_MGC, "get log %s:%s\n", logname, cfg->cfg_instance); + if (cfg->cfg_instance) + match_instance++; + } + + down(&config_llog_lock); + list_for_each(tmp, &config_llog_list) { + cld = list_entry(tmp, struct config_llog_data, cld_list_chain); + if (match_instance && + strcmp(cfg->cfg_instance, cld->cld_cfg.cfg_instance) == 0) + return(cld); + + if (!match_instance && + strcmp(logname, cld->cld_logname) == 0) + return(cld); + } + up(&config_llog_lock); + CERROR("can't get log %s\n", logname); + return(ERR_PTR(-ENOENT)); +} + +static void config_log_put(void) +{ + up(&config_llog_lock); +} + +/* 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) +{ + struct config_llog_data *cld; + int rc; + ENTRY; + + CDEBUG(D_MGC, "adding config log %s:%s\n", logname, cfg->cfg_instance); + + down(&config_llog_lock); + OBD_ALLOC(cld, sizeof(*cld)); + if (!cld) + GOTO(out, rc = -ENOMEM); + OBD_ALLOC(cld->cld_logname, strlen(logname) + 1); + if (!cld->cld_logname) { + OBD_FREE(cld, sizeof(*cld)); + GOTO(out, rc = -ENOMEM); + } + strcpy(cld->cld_logname, logname); + cld->cld_cfg = *cfg; + cld->cld_cfg.cfg_last_idx = 0; + if (cfg->cfg_instance != NULL) { + OBD_ALLOC(cld->cld_cfg.cfg_instance, + strlen(cfg->cfg_instance) + 1); + strcpy(cld->cld_cfg.cfg_instance, cfg->cfg_instance); + } + mgc_logname2resid(logname, &cld->cld_resid); + list_add(&cld->cld_list_chain, &config_llog_list); +out: + up(&config_llog_lock); + RETURN(rc); +} + +/* Stop watching for updates on this log. 2 clients on the same node + may be at different gens, so we need different log info (eg. + already mounted client is at gen 10, but must start a new client + from gen 0.)*/ +static int config_log_end(char *logname, struct config_llog_instance *cfg) +{ + struct config_llog_data *cld; + int rc = 0; + ENTRY; + + cld = config_log_get(logname, cfg); + if (IS_ERR(cld)) + RETURN(PTR_ERR(cld)); + + OBD_FREE(cld->cld_logname, strlen(cld->cld_logname) + 1); + if (cld->cld_cfg.cfg_instance != NULL) + OBD_FREE(cld->cld_cfg.cfg_instance, + strlen(cfg->cfg_instance) + 1); + + list_del(&cld->cld_list_chain); + OBD_FREE(cld, sizeof(*cld)); + config_log_put(); + CDEBUG(D_MGC, "dropped config log %s (%d)\n", logname, rc); + RETURN(rc); +} + +static void config_log_end_all(void) +{ + struct list_head *tmp, *n; + struct config_llog_data *cld; + ENTRY; + + down(&config_llog_lock); + list_for_each_safe(tmp, n, &config_llog_list) { + cld = list_entry(tmp, struct config_llog_data, cld_list_chain); + CERROR("conflog failsafe %s\n", cld->cld_logname); + OBD_FREE(cld->cld_logname, strlen(cld->cld_logname) + 1); + if (cld->cld_cfg.cfg_instance != NULL) + OBD_FREE(cld->cld_cfg.cfg_instance, + strlen(cld->cld_cfg.cfg_instance) + 1); + list_del(&cld->cld_list_chain); + OBD_FREE(cld, sizeof(*cld)); + } + up(&config_llog_lock); + EXIT; +} + + /********************** class fns **********************/ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, @@ -153,10 +296,14 @@ static int mgc_cleanup(struct obd_device *obd) CERROR("failed to cleanup llogging subsystems\n"); ptlrpcd_decref(); - + + config_log_end_all(); + return client_obd_cleanup(obd); } +static struct obd_device *the_mgc; + static int mgc_setup(struct obd_device *obd, obd_count len, void *buf) { int rc; @@ -174,6 +321,7 @@ static int mgc_setup(struct obd_device *obd, obd_count len, void *buf) GOTO(err_cleanup, rc); } + the_mgc = obd; RETURN(rc); err_cleanup: @@ -183,85 +331,89 @@ err_decref: RETURN(rc); } -int mgc_logname2resid(char *logname, struct ldlm_res_id *res_id) -{ - char *name_end; +static int mgc_process_log(struct obd_device *mgc, + struct config_llog_data *cld); - /* fsname is at most 8 chars long at the beginning of the logname - e.g. "lustre-MDT0001" or "lustre" */ - name_end = strchr(logname, '-'); - if (!name_end) - name_end = logname + strlen(logname); - LASSERT(name_end - logname <= 8); +/* FIXME I don't want a thread for every cld; make a list of cld's to requeue + and use only 1 thread. And take an obd ref to the mgc so thread stops before + mgc (the current one is unsafe). */ +/* reenqueue and parse _all_ logs that match the lock */ +static int mgc_async_requeue(void *data) +{ + struct config_llog_data *cld = (struct config_llog_data *)data; + unsigned long flags; + int rc; + ENTRY; - memcpy(&res_id->name[0], logname, name_end - logname); - CDEBUG(D_MGC, "log %s to resid "LPX64"\n", logname, res_id->name[0]); - return 0; + lock_kernel(); + ptlrpc_daemonize(); + SIGNAL_MASK_LOCK(current, flags); + sigfillset(¤t->blocked); + RECALC_SIGPENDING; + SIGNAL_MASK_UNLOCK(current, flags); + THREAD_NAME(current->comm, sizeof(current->comm) - 1, "reQ %s", + cld->cld_logname); + unlock_kernel(); + + CDEBUG(D_MGC, "requeue "LPX64" %s:%s\n", + cld->cld_resid.name[0], cld->cld_logname, + cld->cld_cfg.cfg_instance); + rc = mgc_process_log(the_mgc, cld); + + RETURN(rc); } -EXPORT_SYMBOL(mgc_logname2resid); /* based on ll_mdc_blocking_ast */ static int mgc_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, void *data, int flag) { - int rc; struct lustre_handle lockh; + int rc = 0; ENTRY; - /* FIXME should pass logname,sb as part of lock->l_ast_data, - lustre_get_process_log that. Or based on resource. - Either way, must have one lock per llog. */ - switch (flag) { case LDLM_CB_BLOCKING: /* mgs wants the lock, give it up... */ - LDLM_ERROR(lock, "MGC blocking CB"); - + LDLM_DEBUG(lock, "MGC blocking CB"); ldlm_lock2handle(lock, &lockh); rc = ldlm_cli_cancel(&lockh); - if (rc < 0) { - CDEBUG(D_MGC, "ldlm_cli_cancel: %d\n", rc); - RETURN(rc); - } break; case LDLM_CB_CANCELING: { - char fsname[9]; - - /* We've given up the lock, prepare ourselves to update. - FIXME */ + /* We've given up the lock, prepare ourselves to update. */ LDLM_ERROR(lock, "MGC cancel CB"); - //see struct inode *inode = ll_inode_from_lock(lock); - - memcpy(fsname, &lock->l_resource->lr_name.name[0], 8); - fsname[8] = 0; - CERROR("Lock res "LPX64" (%s)\n", - lock->l_resource->lr_name.name[0], fsname); + CERROR("Lock res "LPX64" (%.8s)\n", + lock->l_resource->lr_name.name[0], + (char *)lock->l_resource->lr_name.name); /* Make sure not to re-enqueue when the mgc is stopping (we get called from client_disconnect_export) */ if (!lock->l_conn_export || - !lock->l_conn_export->exp_obd->u.cli.cl_conn_count) + !lock->l_conn_export->exp_obd->u.cli.cl_conn_count) { + CERROR("Disconnecting, don't requeue\n"); break; + } - CERROR("Re-enqueue all locks on fs '%s'\n", fsname); - /* reenque _all_ logs that match the beginning fsname - - clients and servers */ - - /* in the MGC case I suspect this callback will - trigger a new enqueue for the same lock (in a separate - thread likely, which won't match the just-being-cancelled - lock due to CBPENDING flag) + config llog processing */ - - //update_llog(); - + /* Reenque the lock in a separate thread, because we must + return from this fn before that lock can be taken. */ + rc = kernel_thread(mgc_async_requeue, data, + CLONE_VM | CLONE_FS); + if (rc < 0) + CERROR("Cannot reenque thread: %d\n", rc); + else + rc = 0; break; } default: LBUG(); } - RETURN(0); + if (rc) { + CERROR("%s CB failed %d:\n", flag == LDLM_CB_BLOCKING ? + "blocking" : "cancel", rc); + LDLM_ERROR(lock, "MGC ast"); + } + RETURN(rc); } /* based on ll_get_dir_page and osc_enqueue. */ @@ -271,27 +423,24 @@ static int mgc_enqueue(struct obd_export *exp, struct lov_stripe_md *lsm, void *data, __u32 lvb_len, void *lvb_swabber, struct lustre_handle *lockh) { + struct config_llog_data *cld = (struct config_llog_data *)data; struct obd_device *obd = class_exp2obd(exp); - /* FIXME use fsname, vers and separate locks? see mgs_get_cfg_lock */ - struct ldlm_res_id res_id = { .name = { 12321 } }; int rc; ENTRY; - /* We're only called from obd_mount */ - //LASSERT(mode == LCK_CR); LASSERT(type == LDLM_PLAIN); - CDEBUG(D_MGC, "Enqueue for %s\n", (char *)data); - rc = mgc_logname2resid(data, &res_id); + CDEBUG(D_MGC, "Enqueue for %s (res "LPX64")\n", cld->cld_logname, + cld->cld_resid.name[0]); /* Search for already existing locks.*/ - rc = ldlm_lock_match(obd->obd_namespace, 0, &res_id, type, + rc = ldlm_lock_match(obd->obd_namespace, 0, &cld->cld_resid, type, NULL, mode, lockh); if (rc == 1) RETURN(ELDLM_OK); - rc = ldlm_cli_enqueue(exp, NULL, obd->obd_namespace, res_id, + rc = ldlm_cli_enqueue(exp, NULL, obd->obd_namespace, cld->cld_resid, type, NULL, mode, flags, mgc_blocking_ast, ldlm_completion_ast, NULL, data, NULL, 0, NULL, lockh); @@ -309,6 +458,7 @@ static int mgc_cancel(struct obd_export *exp, struct lov_stripe_md *md, RETURN(0); } +#if 0 static int mgc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, void *karg, void *uarg) { @@ -382,6 +532,7 @@ out: return rc; } +#endif /* Get index and add to config llog, depending on flags */ int mgc_target_add(struct obd_export *exp, struct mgmt_target_info *mti) @@ -608,38 +759,27 @@ static struct obd_export *get_mgs_export(struct obd_device *mgc) /* 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, char *logname, - struct config_llog_instance *cfg) +static int mgc_process_log(struct obd_device *mgc, + struct config_llog_data *cld) { struct llog_ctxt *rctxt; - struct config_llog_data *cld; struct lustre_handle lockh; int rc, rcl, flags = 0; ENTRY; + 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); + rctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT); if (!rctxt) { CERROR("missing llog context\n"); RETURN(-EINVAL); } - /* Remember where we last stopped in this log. - hmm - hold global config lock over the entire llog parse? - I could just 'get' it again after the parse. */ - if (cfg && cfg->cfg_instance) - cld = config_log_get(cfg->cfg_instance); - else - cld = config_log_get(logname); - if (cld && cfg) { - cfg->cfg_last_idx = cld->cld_gen; - CDEBUG(D_MGC, "parsing log %s from %d\n", logname, - cfg->cfg_last_idx); - } - /* Get the cfg lock on the llog */ rcl = mgc_enqueue(get_mgs_export(mgc), NULL, LDLM_PLAIN, NULL, LCK_CR, &flags, NULL, NULL, NULL, - logname, 0, NULL, &lockh); + cld, 0, NULL, &lockh); if (rcl) { CERROR("Can't get cfg lock: %d\n", rcl); config_log_put(); @@ -648,7 +788,9 @@ static int mgc_process_log(struct obd_device *mgc, char *logname, //FIXME Copy the mgs remote log to the local disk - rc = class_config_parse_llog(rctxt, logname, cfg); + /* logname and instance info should be the same, so use our + copy for the update */ + rc = class_config_parse_llog(rctxt, cld->cld_logname, &cld->cld_cfg); /* Now drop the lock so MGS can revoke it */ rcl = mgc_cancel(get_mgs_export(mgc), NULL, LCK_CR, &lockh); @@ -656,15 +798,10 @@ static int mgc_process_log(struct obd_device *mgc, char *logname, CERROR("Can't drop cfg lock: %d\n", rcl); } - /* Remember our gen */ - if (!rc && cld && cfg) - cld->cld_gen = cfg->cfg_last_idx; - config_log_put(); - if (rc) { - LCONSOLE_ERROR("%s: The configuration '%s' could not be read " + LCONSOLE_ERROR("%s: the configuration '%s' could not be read " "(%d) from the MGS.\n", - mgc->obd_name, logname, rc); + mgc->obd_name, cld->cld_logname, rc); } RETURN(rc); @@ -690,16 +827,36 @@ static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf) CDEBUG(D_MGC, "add_target %s %#x\n", mti->mti_svname, mti->mti_flags); rc = mgc_target_add(get_mgs_export(obd), mti); - GOTO(out, rc); + break; } - case LCFG_PARSE_LOG: { - char *logname = lustre_cfg_string(lcfg, 1); + case LCFG_LOG_START: { + struct config_llog_data *cld; struct config_llog_instance *cfg; + char *logname = lustre_cfg_string(lcfg, 1); + cfg = (struct config_llog_instance *)lustre_cfg_buf(lcfg, 2); CDEBUG(D_MGC, "parse_log %s from %d\n", logname, cfg->cfg_last_idx); - rc = mgc_process_log(obd, logname, cfg); - GOTO(out, rc); + + /* We're only called through here on the initial mount */ + config_log_add(logname, cfg); + + cld = config_log_get(logname, cfg); + if (IS_ERR(cld)) + GOTO(out, rc = PTR_ERR(cld)); + + rc = mgc_process_log(obd, cld); + config_log_put(); + 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); @@ -721,7 +878,7 @@ struct obd_ops mgc_obd_ops = { .o_disconnect = client_disconnect_export, .o_enqueue = mgc_enqueue, .o_cancel = mgc_cancel, - .o_iocontrol = mgc_iocontrol, + //.o_iocontrol = mgc_iocontrol, .o_set_info = mgc_set_info, .o_import_event = mgc_import_event, .o_llog_init = mgc_llog_init, diff --git a/lustre/obdclass/llog.c b/lustre/obdclass/llog.c index 2ad2e1e..85668eb 100644 --- a/lustre/obdclass/llog.c +++ b/lustre/obdclass/llog.c @@ -220,8 +220,10 @@ int llog_process(struct llog_handle *loghandle, llog_cb_t cb, if (!buf) RETURN(-ENOMEM); - if (cd != NULL) + if (cd != NULL) { + last_called_index = cd->first_idx; index = cd->first_idx + 1; + } if (cd != NULL && cd->last_idx) last_index = cd->last_idx; else diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index d51f00d..4735dfe 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -836,7 +836,7 @@ int class_config_parse_llog(struct llog_ctxt *ctxt, char *name, rc = llog_process(llh, class_config_llog_handler, cfg, &cd); CDEBUG(D_CONFIG|D_ERROR, "Processed log %s gen %d-%d (%d)\n", name, - cd.first_idx, cd.last_idx, rc); + cd.first_idx + 1, cd.last_idx, rc); if (cfg) cfg->cfg_last_idx = cd.last_idx; diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index c0984a4..4dd2f7d 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -392,109 +392,12 @@ out: #endif -/********************** config llog list **********************/ -DECLARE_MUTEX(config_llog_lock); -struct list_head config_llog_list = LIST_HEAD_INIT(config_llog_list); - -/* Find log and take the global lock (whether found or not) */ -struct config_llog_data *config_log_get(char *name) -{ - struct list_head *tmp; - struct config_llog_data *cld; - down(&config_llog_lock); - list_for_each(tmp, &config_llog_list) { - cld = list_entry(tmp, struct config_llog_data, cld_list_chain); - if (strcmp(name, cld->cld_name) == 0) { - return(cld); - } - } - CERROR("can't get log %s\n", name); - return(NULL); -} - -void config_log_put(void) -{ - up(&config_llog_lock); -} - -/* Add this log to our list of active logs */ -static int config_log_add(char *name) -{ - struct config_llog_data *cld; - char *name_cp; - int rc; - ENTRY; - - CDEBUG(D_MOUNT, "adding config log %s\n", name); - if (config_log_get(name)) { - GOTO(out, rc = -EEXIST); - } - - OBD_ALLOC(cld, sizeof(*cld)); - if (!cld) - GOTO(out, rc = -ENOMEM); - OBD_ALLOC(name_cp, strlen(name) + 1); - if (!name_cp) { - OBD_FREE(cld, sizeof(*cld)); - GOTO(out, rc = -ENOMEM); - } - strcpy(name_cp, name); - - cld->cld_name = name_cp; - cld->cld_gen = 0; - list_add(&cld->cld_list_chain, &config_llog_list); -out: - config_log_put(); - RETURN(rc); -} - - -/* Stop watching for updates on this log. 2 clients on the same node - may be at different gens, so we need different log info (eg. - already mounted client is at gen 10, but must start a new client - from gen 0.)*/ -int config_log_end(char *name) -{ - struct config_llog_data *cld; - int rc = 0; - ENTRY; - - cld = config_log_get(name); - if (!cld) - GOTO(out, rc = -ENOENT); - OBD_FREE(cld->cld_name, strlen(cld->cld_name) + 1); - list_del(&cld->cld_list_chain); - OBD_FREE(cld, sizeof(*cld)); -out: - config_log_put(); - CDEBUG(D_MOUNT, "dropping config log %s (%d)\n", name, rc); - RETURN(rc); -} - -static void config_log_end_all(void) -{ - struct list_head *tmp, *n; - struct config_llog_data *cld; - ENTRY; - - down(&config_llog_lock); - list_for_each_safe(tmp, n, &config_llog_list) { - cld = list_entry(tmp, struct config_llog_data, cld_list_chain); - CERROR("conflog failsafe %s\n", cld->cld_name); - OBD_FREE(cld->cld_name, strlen(cld->cld_name) + 1); - list_del(&cld->cld_list_chain); - OBD_FREE(cld, sizeof(*cld)); - } - up(&config_llog_lock); - EXIT; -} - /**************** config llog ********************/ /* Get a config log from the MGS and process it. This func is called for both clients and servers. */ -int config_log_start(struct super_block *sb, char *logname, - struct config_llog_instance *cfg) +int lustre_process_log(struct super_block *sb, char *logname, + struct config_llog_instance *cfg) { struct lustre_cfg *lcfg; struct lustre_cfg_bufs bufs; @@ -504,16 +407,13 @@ int config_log_start(struct super_block *sb, char *logname, ENTRY; LASSERT(mgc); + LASSERT(cfg); - if (cfg && cfg->cfg_instance) - config_log_add(cfg->cfg_instance); - else - config_log_add(logname); - + /* mgc_process_config */ lustre_cfg_bufs_reset(&bufs, mgc->obd_name); lustre_cfg_bufs_set_string(&bufs, 1, logname); lustre_cfg_bufs_set(&bufs, 2, cfg, sizeof(*cfg)); - lcfg = lustre_cfg_new(LCFG_PARSE_LOG, &bufs); + lcfg = lustre_cfg_new(LCFG_LOG_START, &bufs); rc = obd_process_config(mgc, sizeof(*lcfg), lcfg); lustre_cfg_free(lcfg); @@ -551,6 +451,30 @@ int config_log_start(struct super_block *sb, char *logname, RETURN(rc); } + +int lustre_end_log(struct super_block *sb, char *logname, + struct config_llog_instance *cfg) +{ + struct lustre_cfg *lcfg; + struct lustre_cfg_bufs bufs; + struct lustre_sb_info *lsi = s2lsi(sb); + struct obd_device *mgc = lsi->lsi_mgc; + int rc; + ENTRY; + + LASSERT(mgc); + + /* mgc_process_config */ + lustre_cfg_bufs_reset(&bufs, mgc->obd_name); + lustre_cfg_bufs_set_string(&bufs, 1, logname); + if (cfg) + lustre_cfg_bufs_set(&bufs, 2, cfg, sizeof(*cfg)); + lcfg = lustre_cfg_new(LCFG_LOG_END, &bufs); + rc = obd_process_config(mgc, sizeof(*lcfg), lcfg); + lustre_cfg_free(lcfg); + RETURN(0); +} + /**************** obd start *******************/ static int do_lcfg(char *cfgname, lnet_nid_t nid, int cmd, @@ -814,8 +738,6 @@ static int lustre_stop_mgc(struct super_block *sb) } /* class_import_put will get rid of the additional connections */ - config_log_end_all(); - RETURN(0); } @@ -1037,7 +959,7 @@ static int server_start_targets(struct super_block *sb, struct vfsmount *mnt) /* Start targets using the llog named for the target */ cfg.cfg_instance = NULL; - rc = config_log_start(sb, lsi->lsi_ldd->ldd_svname, &cfg); + rc = lustre_process_log(sb, lsi->lsi_ldd->ldd_svname, &cfg); if (rc) { CERROR("failed to start server %s: %d\n", lsi->lsi_ldd->ldd_svname, rc); @@ -1215,7 +1137,8 @@ static void server_put_super(struct super_block *sb) CDEBUG(D_MOUNT, "server put_super %s\n", lsi->lsi_ldd->ldd_svname); - config_log_end(lsi->lsi_ldd->ldd_svname); + /* tell the mgc to drop the config log */ + lustre_end_log(sb, lsi->lsi_ldd->ldd_svname, NULL); obd = class_name2obd(lsi->lsi_ldd->ldd_svname); if (obd) { @@ -1699,10 +1622,8 @@ int lustre_unregister_fs(void) EXPORT_SYMBOL(lustre_register_client_fill_super); EXPORT_SYMBOL(lustre_common_put_super); -EXPORT_SYMBOL(config_log_start); -EXPORT_SYMBOL(config_log_end); -EXPORT_SYMBOL(config_log_get); -EXPORT_SYMBOL(config_log_put); +EXPORT_SYMBOL(lustre_process_log); +EXPORT_SYMBOL(lustre_end_log); EXPORT_SYMBOL(server_get_mount); EXPORT_SYMBOL(server_put_mount); -- 1.8.3.1