From: nathan Date: Thu, 29 Dec 2005 00:24:17 +0000 (+0000) Subject: Branch b1_4_mountconf X-Git-Tag: v1_8_0_110~486^4~95 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=bc008d80c14b2fd75d179e2238dd315dcd76187d;p=fs%2Flustre-release.git Branch b1_4_mountconf b=8192,9867 - move llog parsing into mgc - track "used" logs to keep config generation info - add statfs for df info on the server mounts - just report underlying disk info (huanghua) - more LCFG_MARKER processing --- diff --git a/lustre/include/linux/lustre_cfg.h b/lustre/include/linux/lustre_cfg.h index 124141c..d6bb24a 100644 --- a/lustre/include/linux/lustre_cfg.h +++ b/lustre/include/linux/lustre_cfg.h @@ -50,7 +50,8 @@ enum lcfg_command_type { LCFG_LOV_ADD_OBD = 0x00cf00d, LCFG_LOV_DEL_OBD = 0x00cf00e, LCFG_PARAM = 0x00cf00f, - LCFG_MARKER = 0x00cf010 + LCFG_MARKER = 0x00cf010, + LCFG_PARSE_LOG = 0x00cf011, }; struct lustre_cfg_bufs { diff --git a/lustre/include/linux/lustre_disk.h b/lustre/include/linux/lustre_disk.h index a9e5a77..d035281 100644 --- a/lustre/include/linux/lustre_disk.h +++ b/lustre/include/linux/lustre_disk.h @@ -192,11 +192,9 @@ struct ll_sb_info; struct lustre_sb_info { int lsi_flags; - //struct lvfs_run_ctxt lsi_ctxt; /* mount context */ struct obd_device *lsi_mgc; /* mgc obd */ struct lustre_mount_data *lsi_lmd; /* mount command info */ struct lustre_disk_data *lsi_ldd; /* mount info on-disk */ - //struct fsfilt_operations *lsi_fsops; struct ll_sb_info *lsi_llsbi; /* add'l client sbi info */ struct vfsmount *lsi_srv_mnt; /* the one server mount */ atomic_t lsi_mounts; /* references to the srv_mnt */ @@ -236,8 +234,11 @@ void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb)); int lustre_common_put_super(struct super_block *sb); struct lustre_mount_info *server_get_mount(char *name); int server_put_mount(char *name, struct vfsmount *mnt); -int lustre_get_process_log(struct super_block *, char *, +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); #endif diff --git a/lustre/include/linux/lustre_log.h b/lustre/include/linux/lustre_log.h index 96cd5d0..52ad5c1 100644 --- a/lustre/include/linux/lustre_log.h +++ b/lustre/include/linux/lustre_log.h @@ -73,6 +73,7 @@ struct llog_fill_rec_data { obd_count lfd_ogen; /* object group */ }; + /* llog.c - general API */ typedef int (*llog_cb_t)(struct llog_handle *, struct llog_rec_hdr *, void *); typedef int (*llog_fill_rec_cb_t)(struct llog_rec_hdr *rec, void *data); @@ -106,6 +107,14 @@ 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/lustre_mgs.h b/lustre/include/linux/lustre_mgs.h index 26ba68b..fc01dd6 100644 --- a/lustre/include/linux/lustre_mgs.h +++ b/lustre/include/linux/lustre_mgs.h @@ -27,7 +27,7 @@ struct fs_db { struct list_head fd_list; void* fd_index_map; __u32 fd_flags; - __u32 fd_last_step; + __u32 fd_gen; //FIXME add a semaphore for locking the fs_db (and logs) }; diff --git a/lustre/include/linux/obd_class.h b/lustre/include/linux/obd_class.h index 9064072..078ee34 100644 --- a/lustre/include/linux/obd_class.h +++ b/lustre/include/linux/obd_class.h @@ -106,8 +106,9 @@ void class_decref(struct obd_device *obd); /* Passed as data param to class_config_parse_llog */ struct config_llog_instance { - char * cfg_instance; + char * cfg_instance; struct obd_uuid cfg_uuid; + int cfg_last_idx; /* for partial llog processing */ }; int class_config_parse_llog(struct llog_ctxt *ctxt, char *name, struct config_llog_instance *cfg); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 89af4ff..c4ab3b8 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 = lustre_get_process_log(sb, profilenm, &cfg); + err = config_log_start(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) { + char ll_instance[sizeof(sb) * 2 + 1]; struct obd_device *obd; struct lustre_sb_info *lsi = s2lsi(sb); struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -581,6 +582,10 @@ void ll_put_super(struct super_block *sb) ENTRY; CDEBUG(D_VFSTRACE, "VFS Op: sb %p - %s\n", sb, profilenm); + + sprintf(ll_instance, "%p", sb); + config_log_end(ll_instance); + obd = class_exp2obd(sbi->ll_mdc_exp); if (obd) { int next = 0; @@ -601,7 +606,7 @@ void ll_put_super(struct super_block *sb) if (profilenm) class_del_profile(profilenm); - + ll_free_sbi(sb); lsi->lsi_llsbi = NULL; diff --git a/lustre/lov/lov_log.c b/lustre/lov/lov_log.c index 61088d6..587a8c9 100644 --- a/lustre/lov/lov_log.c +++ b/lustre/lov/lov_log.c @@ -101,7 +101,9 @@ static int lov_llog_origin_connect(struct llog_ctxt *ctxt, int count, int i, rc = 0; ENTRY; - LASSERT(lov->desc.ld_tgt_count == count); + if (lov->desc.ld_tgt_count != count) + CERROR("Origin connect %d != %d\n", + lov->desc.ld_tgt_count, count); for (i = 0, tgt = lov->tgts; i < lov->desc.ld_tgt_count; i++, tgt++) { struct obd_device *child; struct llog_ctxt *cctxt; diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index 5cd9a56..8b1dc1c 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -49,7 +49,7 @@ #include "mgc_internal.h" - +/********************** class fns **********************/ static int mgc_fs_setup(struct obd_device *obd, struct super_block *sb, struct vfsmount *mnt) @@ -549,7 +549,136 @@ static int mgc_llog_finish(struct obd_device *obd, int count) RETURN(rc); } -/* reuse the client_import_[add/del]_conn*/ +/* Get the client export to the MGS */ +static struct obd_export *get_mgs_export(struct obd_device *mgc) +{ + struct obd_export *exp, *n; + + /* FIXME is this a Bad Idea? Should I just store this export + somewhere in the u.cli? */ + + /* There should be exactly 2 exports in the mgc, the mgs export and + the mgc self-export, in that order. So just return the list head. */ + LASSERT(!list_empty(&mgc->obd_exports)); + LASSERT(mgc->obd_num_exports == 2); + list_for_each_entry_safe(exp, n, &mgc->obd_exports, exp_obd_chain) { + LASSERT(exp != mgc->obd_self_export); + break; + } + /*FIXME there's clearly a better way, but I'm too confused to sort it + out now... + exp = &list_entry(&mgc->obd_exports->head, export_obd, exp_obd_chain); + */ + return exp; +} + +/* 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) +{ + struct llog_ctxt *rctxt; + struct config_llog_data *cld; + struct lustre_handle lockh; + int rc, rcl, flags = 0; + ENTRY; + + CDEBUG(D_MGC, "parsing config log %s\n", logname); + + 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); + if (rcl) { + CERROR("Can't get cfg lock: %d\n", rcl); + config_log_put(); + RETURN(rcl); + } + + //FIXME Copy the mgs remote log to the local disk + + rc = class_config_parse_llog(rctxt, logname, cfg); + + /* Now drop the lock so MGS can revoke it */ + rcl = mgc_cancel(get_mgs_export(mgc), NULL, LCK_CR, &lockh); + if (rcl) { + 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 " + "(%d) from the MGS.\n", + mgc->obd_name, logname, rc); + } + + 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: + case LCFG_LOV_DEL_OBD: { + struct mgmt_target_info *mti; + + if (LUSTRE_CFG_BUFLEN(lcfg, 1) != + sizeof(struct mgmt_target_info)) + GOTO(out, rc = -EINVAL); + + mti = (struct mgmt_target_info *)lustre_cfg_buf(lcfg, 1); + 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); + } + case LCFG_PARSE_LOG: { + char *logname = lustre_cfg_string(lcfg, 1); + struct config_llog_instance *cfg; + cfg = (struct config_llog_instance *)lustre_cfg_buf(lcfg, 2); + CDEBUG(D_MGC, "parse_log %s from %d\n", logname, + cfg->cfg_last_idx); + mgc_process_log(obd, logname, cfg); + GOTO(out, rc); + } + 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, @@ -565,6 +694,7 @@ struct obd_ops mgc_obd_ops = { .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) diff --git a/lustre/mgs/mgs_llog.c b/lustre/mgs/mgs_llog.c index 80c4ee7..45c69ff 100644 --- a/lustre/mgs/mgs_llog.c +++ b/lustre/mgs/mgs_llog.c @@ -83,8 +83,7 @@ static int db_handler(struct llog_handle *llh, struct llog_rec_hdr *rec, if (lcfg->lcfg_command == LCFG_MARKER) { struct cfg_marker *marker; marker = lustre_cfg_buf(lcfg, 1); - db->fd_last_step = - max(db->fd_last_step, marker->cm_step); + db->fd_gen = max(db->fd_gen, marker->cm_step); CDEBUG(D_MGS, "marker %d %s\n", marker->cm_step, marker->cm_comment); } @@ -431,8 +430,8 @@ static int record_marker(struct obd_device *obd, struct llog_handle *llh, CDEBUG(D_MGS, "lcfg marker\n"); if (flags & CM_START) - db->fd_last_step++; - marker.cm_step = db->fd_last_step; + db->fd_gen++; + marker.cm_step = db->fd_gen; marker.cm_flags = flags; strncpy(marker.cm_comment, comment, sizeof(marker.cm_comment)); lustre_cfg_bufs_reset(&bufs, NULL); @@ -632,6 +631,7 @@ static int mgs_write_log_lov(struct obd_device *obd, struct fs_db *db, rc = record_marker(obd, llh, db, CM_END, "lov setup"); rc = record_end_log(obd, &llh); + OBD_FREE(lovdesc, sizeof(*lovdesc)); RETURN(rc); } diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index 616a02f..cc5337d 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -310,10 +310,10 @@ void class_obd_list(void) status = "AT"; else status = "--"; - CDEBUG(D_WARNING, "%3d %s %s %s %s %d\n", - i, status, obd->obd_type->typ_name, - obd->obd_name, obd->obd_uuid.uuid, - atomic_read(&obd->obd_refcount)); + LCONSOLE_WARN("%3d %s %s %s %s %d\n", + i, status, obd->obd_type->typ_name, + obd->obd_name, obd->obd_uuid.uuid, + atomic_read(&obd->obd_refcount)); } spin_unlock(&obd_dev_lock); return; diff --git a/lustre/obdclass/llog.c b/lustre/obdclass/llog.c index 2a4297f..2ad2e1e 100644 --- a/lustre/obdclass/llog.c +++ b/lustre/obdclass/llog.c @@ -211,7 +211,7 @@ int llog_process(struct llog_handle *loghandle, llog_cb_t cb, char *buf; __u64 cur_offset = LLOG_CHUNK_SIZE; int rc = 0, index = 1, last_index; - int saved_index = 0; + int saved_index = 0, last_called_index = 0; ENTRY; LASSERT(llh); @@ -289,6 +289,7 @@ int llog_process(struct llog_handle *loghandle, llog_cb_t cb, /* if set, process the callback on this record */ if (ext2_test_bit(index, llh->llh_bitmap)) { rc = cb(loghandle, rec, data); + last_called_index = index; if (rc == LLOG_PROC_BREAK) { CWARN("recovery from log: "LPX64":%x" " stopped\n", @@ -310,6 +311,8 @@ int llog_process(struct llog_handle *loghandle, llog_cb_t cb, } out: + if (cd != NULL) + cd->last_idx = last_called_index; if (buf) OBD_FREE(buf, LLOG_CHUNK_SIZE); RETURN(rc); diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 7614797..d3e5a34 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -43,6 +43,8 @@ #include +/********************** class fns **********************/ + /* Create a new device and set the type, name and uuid. If * successful, the new device can be accessed by either name or uuid. */ @@ -628,8 +630,6 @@ int class_process_config(struct lustre_cfg *lcfg) case LCFG_DEL_MOUNTOPT: { CDEBUG(D_IOCTL, "mountopt: profile %s\n", lustre_cfg_string(lcfg, 1)); - /* set these mount options somewhere, so ll_fill_super - * can find them. */ class_del_profile(lustre_cfg_string(lcfg, 1)); GOTO(out, err = 0); } @@ -652,9 +652,8 @@ int class_process_config(struct lustre_cfg *lcfg) } case LCFG_MARKER: { struct cfg_marker *marker; - LCONSOLE_WARN("LCFG_MARKER not yet implemented.\n"); marker = lustre_cfg_buf(lcfg, 1); - CDEBUG(D_WARNING, "%d (%x) %s\n", marker->cm_step, + CDEBUG(D_IOCTL, "marker %d (%#x) %s\n", marker->cm_step, marker->cm_flags, marker->cm_comment); GOTO(out, err = 0); } @@ -734,6 +733,13 @@ static int class_config_llog_handler(struct llog_handle * handle, if (rc) GOTO(out, rc); + /* FIXME check cm_flags for skip - must save state, + probably in handle + if (lcfg->lcfg_command == LCFG_MARKER) { + struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1); + } + */ + lustre_cfg_bufs_init(&bufs, lcfg); if (cfg && cfg->cfg_instance && LUSTRE_CFG_BUFLEN(lcfg, 0) > 0) { @@ -755,7 +761,8 @@ static int class_config_llog_handler(struct llog_handle * handle, are unique */ if (cfg && cfg->cfg_instance && lcfg->lcfg_command == LCFG_ATTACH) { - lustre_cfg_bufs_set_string(&bufs, 2, cfg->cfg_uuid.uuid); + lustre_cfg_bufs_set_string(&bufs, 2, + cfg->cfg_uuid.uuid); } lcfg_new = lustre_cfg_new(lcfg->lcfg_command, &bufs); @@ -779,7 +786,7 @@ static int class_config_llog_handler(struct llog_handle * handle, } lcfg_new->lcfg_nal = 0; /* illegal value for obsolete field */ - + rc = class_process_config(lcfg_new); lustre_cfg_free(lcfg_new); @@ -803,6 +810,7 @@ out: int class_config_parse_llog(struct llog_ctxt *ctxt, char *name, struct config_llog_instance *cfg) { + struct llog_process_cat_data cd = {0, 0}; struct llog_handle *llh; int rc, rc2; ENTRY; @@ -816,7 +824,16 @@ int class_config_parse_llog(struct llog_ctxt *ctxt, char *name, if (rc) GOTO(parse_out, rc); - rc = llog_process(llh, class_config_llog_handler, cfg, NULL); + /* continue processing from where we last stopped to end-of-log */ + if (cfg) + cd.first_idx = cfg->cfg_last_idx; + cd.last_idx = 0; + + rc = llog_process(llh, class_config_llog_handler, cfg, &cd); + + CERROR("Processed %d-%d\n", cd.first_idx, cd.last_idx); + cfg->cfg_last_idx = cd.last_idx; + parse_out: rc2 = llog_close(llh); if (rc == 0) @@ -825,7 +842,6 @@ parse_out: RETURN(rc); } -#define D_DUMP D_INFO|D_WARNING int class_config_dump_handler(struct llog_handle * handle, struct llog_rec_hdr *rec, void *data) { @@ -850,7 +866,7 @@ int class_config_dump_handler(struct llog_handle * handle, GOTO(out, rc); lcfg = (struct lustre_cfg *)cfg_buf; - ptr += snprintf(ptr, end-ptr, "\n cmd=%05x ", + ptr += snprintf(ptr, end-ptr, "cmd=%05x ", lcfg->lcfg_command); if (lcfg->lcfg_flags) { ptr += snprintf(ptr, end-ptr, "flags=%#08x ", @@ -861,19 +877,26 @@ int class_config_dump_handler(struct llog_handle * handle, lcfg->lcfg_num); } if (lcfg->lcfg_nid) { - ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n", + ptr += snprintf(ptr, end-ptr, "nid=%s("LPX64")\n ", libcfs_nid2str(lcfg->lcfg_nid), lcfg->lcfg_nid); } - for (i = 0; i < lcfg->lcfg_bufcount; i++) { - ptr += snprintf(ptr, end-ptr, "%d:%s ", i, - lustre_cfg_string(lcfg, i)); + if (lcfg->lcfg_command == LCFG_MARKER) { + struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1); + ptr += snprintf(ptr, end-ptr, "marker=%d(%#x)'%s'", + marker->cm_step, marker->cm_flags, + marker->cm_comment); + } else { + for (i = 0; i < lcfg->lcfg_bufcount; i++) { + ptr += snprintf(ptr, end-ptr, "%d:%s ", i, + lustre_cfg_string(lcfg, i)); + } } - CDEBUG(D_DUMP, "%s\n", outstr); + LCONSOLE_INFO(" %s\n", outstr); } else if (rec->lrh_type == PTL_CFG_REC) { - CDEBUG(D_DUMP, "Obsolete pcfg command\n"); + LCONSOLE_INFO("Obsolete pcfg command\n"); } else { - CERROR("unhandled lrh_type: %#x\n", rec->lrh_type); + LCONSOLE_INFO("unhandled lrh_type: %#x\n", rec->lrh_type); rc = -EINVAL; } out: @@ -888,7 +911,7 @@ int class_config_dump_llog(struct llog_ctxt *ctxt, char *name, int rc, rc2; ENTRY; - CDEBUG(D_DUMP, "Dumping config log %s\n", name); + LCONSOLE_INFO("Dumping config log %s\n", name); rc = llog_create(ctxt, &llh, NULL, name); if (rc) @@ -904,7 +927,7 @@ parse_out: if (rc == 0) rc = rc2; - CDEBUG(D_DUMP, "End config log %s\n", name); + LCONSOLE_INFO("End config log %s\n", name); RETURN(rc); } diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index 5e3c26a..11161f8 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -39,24 +39,22 @@ static int (*client_fill_super)(struct super_block *sb) = NULL; + /*********** mount lookup *********/ + DECLARE_MUTEX(lustre_mount_info_lock); -struct list_head lustre_mount_info_list = LIST_HEAD_INIT(lustre_mount_info_list); +struct list_head server_mount_info_list = LIST_HEAD_INIT(server_mount_info_list); static struct lustre_mount_info *server_find_mount(char *name) { struct list_head *tmp; struct lustre_mount_info *lmi; - int found = 0; - list_for_each(tmp, &lustre_mount_info_list) { + + list_for_each(tmp, &server_mount_info_list) { lmi = list_entry(tmp, struct lustre_mount_info, lmi_list_chain); - if (strcmp(name, lmi->lmi_name) == 0) { - found++; - break; - } + if (strcmp(name, lmi->lmi_name) == 0) + return(lmi); } - if (found) - return(lmi); return(NULL); } @@ -93,7 +91,7 @@ static int server_register_mount(char *name, struct super_block *sb, lmi->lmi_name = name_cp; lmi->lmi_sb = sb; lmi->lmi_mnt = mnt; - list_add(&lmi->lmi_list_chain, &lustre_mount_info_list); + list_add(&lmi->lmi_list_chain, &server_mount_info_list); up(&lustre_mount_info_lock); return 0; @@ -129,7 +127,7 @@ static void server_deregister_mount_all(struct vfsmount *mnt) return; down(&lustre_mount_info_lock); - list_for_each_safe(tmp, n, &lustre_mount_info_list) { + list_for_each_safe(tmp, n, &server_mount_info_list) { lmi = list_entry(tmp, struct lustre_mount_info, lmi_list_chain); if (lmi->lmi_mnt == mnt) { CERROR("Deregister failsafe %s\n", lmi->lmi_name); @@ -224,18 +222,18 @@ static void ldd_print(struct lustre_disk_data *ldd) { int i; - CDEBUG(D_MOUNT, "disk data\n"); - CDEBUG(D_MOUNT, "config: %d\n", ldd->ldd_config_ver); - CDEBUG(D_MOUNT, "fs: %s\n", ldd->ldd_fsname); - CDEBUG(D_MOUNT, "server: %s\n", ldd->ldd_svname); - CDEBUG(D_MOUNT, "index: %04x\n", ldd->ldd_svindex); - CDEBUG(D_MOUNT, "flags: %#x\n", ldd->ldd_flags); - CDEBUG(D_MOUNT, "diskfs: %s\n", MT_STR(ldd)); - CDEBUG(D_MOUNT, "options: %s\n", ldd->ldd_mount_opts); + LCONSOLE_WARN(" disk data:\n"); + LCONSOLE_WARN("config: %d\n", ldd->ldd_config_ver); + LCONSOLE_WARN("fs: %s\n", ldd->ldd_fsname); + LCONSOLE_WARN("server: %s\n", ldd->ldd_svname); + LCONSOLE_WARN("index: %04x\n", ldd->ldd_svindex); + LCONSOLE_WARN("flags: %#x\n", ldd->ldd_flags); + LCONSOLE_WARN("diskfs: %s\n", MT_STR(ldd)); + LCONSOLE_WARN("options: %s\n", ldd->ldd_mount_opts); if (!ldd->ldd_mgsnid_count) - CDEBUG(D_MOUNT, "no MGS nids\n"); + LCONSOLE_WARN("no MGS nids\n"); else for (i = 0; i < ldd->ldd_mgsnid_count; i++) { - CDEBUG(D_MOUNT, "mgs nid %d: %s\n", i, + LCONSOLE_WARN("mgs nid %d: %s\n", i, libcfs_nid2str(ldd->ldd_mgsnid[i])); } } @@ -374,77 +372,136 @@ out: } #endif -/**************** config llog ********************/ -/* Get the client export to the MGS */ -static struct obd_export *get_mgs_export(struct obd_device *mgc) +/********************** 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 obd_export *exp, *n; + 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); +} - /* FIXME is this a Bad Idea? Should I just store this export - somewhere in the u.cli? Slightly annoying because of layering */ +void config_log_put(void) +{ + up(&config_llog_lock); +} - /* There should be exactly 2 exports in the mgc, the mgs export and - the mgc self-export, in that order. So just return the list head. */ - LASSERT(!list_empty(&mgc->obd_exports)); - LASSERT(mgc->obd_num_exports == 2); - list_for_each_entry_safe(exp, n, &mgc->obd_exports, exp_obd_chain) { - LASSERT(exp != mgc->obd_self_export); - break; +static int config_log_add(char *name) +{ + struct config_llog_data *cld; + char *name_cp; + int rc; + ENTRY; + + CDEBUG(D_MOUNT, "adding config llog %s\n", name); + if (config_log_get(name)) { + GOTO(out, rc = -EEXIST); } - /*FIXME there's clearly a better way, but I'm too confused to sort it - out now... - exp = &list_entry(&mgc->obd_exports->head, export_obd, exp_obd_chain); - */ - return exp; + + 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, "removed config llog %s %d\n", name, rc); + RETURN(rc); +} + +static void config_log_end_all(void) +{ + struct list_head *tmp, *n; + struct config_llog_data *cld; + + 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); } +/**************** config llog ********************/ + /* Get a config log from the MGS and process it. This func is called for both clients and servers. */ -/* FIXME maybe it makes more sense for this to be a mgc func, not - a mount func. We could make this mgc_process_config */ -int lustre_get_process_log(struct super_block *sb, char *logname, +int config_log_start(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; - struct llog_ctxt *rctxt, *lctxt; - struct lustre_handle lockh; - int rc, rcl, flags = 0; + struct llog_ctxt *lctxt; + int rc; + ENTRY; + LASSERT(mgc); - CDEBUG(D_MOUNT, "parsing config log %s\n", logname); + if (cfg && cfg->cfg_instance) + config_log_add(cfg->cfg_instance); + else + config_log_add(logname); - rctxt = llog_get_context(mgc, LLOG_CONFIG_REPL_CTXT); lctxt = llog_get_context(mgc, LLOG_CONFIG_ORIG_CTXT); - if (!lctxt || !rctxt) { + if (!lctxt) { CERROR("missing llog context\n"); return(-EINVAL); } - /* Get the cfg lock */ - rcl = obd_enqueue(get_mgs_export(mgc), NULL, LDLM_PLAIN, NULL, - LCK_CR, &flags, NULL, NULL, NULL, - logname, 0, NULL, &lockh); - if (rcl) { - CERROR("Can't get cfg lock: %d\n", rcl); - return (rcl); - } - - //FIXME Copy the mgs remote log to the local disk + 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); + rc = obd_process_config(mgc, sizeof(*lcfg), lcfg); + lustre_cfg_free(lcfg); -#if 0 - /* For debugging, it's useful to just dump the log */ - class_config_dump_llog(rctxt, logname, cfg); -#endif - rc = class_config_parse_llog(rctxt, logname, cfg); - - /* Now drop the lock so MGS can revoke it */ - rcl = obd_cancel(get_mgs_export(mgc), NULL, LCK_CR, &lockh); - if (rcl) { - CERROR("Can't drop cfg lock: %d\n", rcl); - } - if (rc && !lmd_is_client(lsi->lsi_lmd)) { int rc2; LCONSOLE_INFO("%s: The configuration '%s' could not be read " @@ -466,10 +523,8 @@ int lustre_get_process_log(struct super_block *sb, char *logname, mgc->obd_name, logname, rc); } - CDEBUG(D_MOUNT, "after lustre_get_process_log %s\n", logname); class_obd_list(); - - return (rc); + RETURN(rc); } /**************** obd start *******************/ @@ -576,6 +631,8 @@ static int server_stop_mgs(struct super_block *sb) return rc; } +static struct obd_export *mgc_mgs_export = NULL; + /* Set up a mgcobd to process startup logs */ static int lustre_start_mgc(struct super_block *sb) { @@ -617,8 +674,12 @@ static int lustre_start_mgc(struct super_block *sb) return rc; /* Generate a unique uuid for each MGC - use the 1st non-loopback nid */ - /* FIXME if no loopback? Use lustre_generate_random_uuid? */ - rc = LNetGetId(1, &id); + i = 0; + while ((rc = LNetGetId(i++, &id)) != -ENOENT) { + if (LNET_NETTYP(LNET_NIDNET(id.nid)) == LOLND) + continue; + break; + } OBD_ALLOC(uuid, sizeof(struct obd_uuid)); sprintf(uuid, "mgc_"LPX64, id.nid); /* Start the MGC */ @@ -667,8 +728,10 @@ static int lustre_start_mgc(struct super_block *sb) CERROR("connect failed %d\n", rc); goto out; } + exp = class_conn2export(&mgc_conn); - LASSERT(exp == get_mgs_export(obd)); + /* only 1 mgc, only 1 connection to the mgs */ + mgc_mgs_export = exp; /* And keep a refcount of servers/clients who started with "mount", so we know when we can get rid of the mgc. */ @@ -701,7 +764,9 @@ static int lustre_stop_mgc(struct super_block *sb) return -EBUSY; } - obd_disconnect(get_mgs_export(obd)); + if (mgc_mgs_export) + obd_disconnect(mgc_mgs_export); + mgc_mgs_export = NULL; rc = class_manual_cleanup(obd); if (rc) @@ -718,6 +783,9 @@ static int lustre_stop_mgc(struct super_block *sb) libcfs_nid2str(nid), rc); } /* class_import_put will get rid of the additional connections */ + + config_log_end_all(); + return 0; } @@ -836,15 +904,8 @@ static int server_add_target(struct super_block *sb, struct vfsmount *mnt) libcfs_nid2str(mti->mti_nid), mti->mti_stripe_index); /* Register the target */ - /* FIXME use ioctl instead? eg - struct obd_ioctl_data ioc_data = { 0 }; - ioc_data.ioc_inllen1 = strlen(ldd->ldd_svname) + 1; - ioc_data.ioc_inlbuf1 = ldd->ldd_svname; - - rc = obd_iocontrol(OBD_IOC_START, obd->obd_self_export, - sizeof ioc_data, &ioc_data, NULL); - */ - rc = obd_set_info(get_mgs_export(mgc), + /* FIXME use mdc_process_config instead */ + rc = obd_set_info(mgc_mgs_export, strlen("add_target"), "add_target", sizeof(*mti), mti); CDEBUG(D_MOUNT, "disconnect"); @@ -921,7 +982,8 @@ static int server_start_targets(struct super_block *sb, struct vfsmount *mnt) server_mgc_set_fs(lsi->lsi_mgc, sb); /* Get a new index if needed */ - if (lsi->lsi_ldd->ldd_flags & (LDD_F_NEED_INDEX | LDD_F_NEED_REGISTER)) { + if (lsi->lsi_ldd->ldd_flags & + (LDD_F_NEED_INDEX | LDD_F_NEED_REGISTER)) { CDEBUG(D_MOUNT, "Need new target index from MGS\n"); rc = server_add_target(sb, mnt); if (rc) { @@ -931,14 +993,15 @@ static int server_start_targets(struct super_block *sb, struct vfsmount *mnt) } } - /* Let the target look up the mount using the target's name. */ + /* Let the target look up the mount using the target's name + (we can't pass the sb or mnt through class_process_config.) */ rc = server_register_mount(lsi->lsi_ldd->ldd_svname, sb, mnt); if (rc) goto out; - /* The MGC starts targets using the llog named with the target name */ + /* Start targets using the llog named for the target */ cfg.cfg_instance = NULL; - rc = lustre_get_process_log(sb, lsi->lsi_ldd->ldd_svname, &cfg); + rc = config_log_start(sb, lsi->lsi_ldd->ldd_svname, &cfg); if (rc) { CERROR("failed to start server %s: %d\n", lsi->lsi_ldd->ldd_svname, rc); @@ -1117,6 +1180,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); + obd = class_name2obd(lsi->lsi_ldd->ldd_svname); if (obd) { CDEBUG(D_MOUNT, "stopping %s\n", obd->obd_name); @@ -1163,16 +1228,40 @@ static void server_umount_begin(struct super_block *sb) lsi->lsi_flags |= LSI_UMOUNT_FAILOVER; } -#define log2(n) ffz(~(n)) -#define LUSTRE_SUPER_MAGIC 0x0BD00BD1 +static int server_statfs (struct super_block *sb, struct kstatfs *buf) +{ + struct vfsmount *mnt = s2lsi(sb)->lsi_srv_mnt; + + if (mnt && mnt->mnt_sb && mnt->mnt_sb->s_op->statfs) { + int rc = mnt->mnt_sb->s_op->statfs(mnt->mnt_sb, buf); + if (!rc) { + buf->f_type = sb->s_magic; + return 0; + } + } + + /* just return 0 */ + buf->f_type = sb->s_magic; + buf->f_bsize = sb->s_blocksize; + buf->f_blocks = 1; + buf->f_bfree = 0; + buf->f_bavail = 0; + buf->f_files = 1; + buf->f_ffree = 0; + buf->f_namelen = NAME_MAX; + return 0; +} static struct super_operations server_ops = { - //.statfs = NULL, .put_super = server_put_super, .umount_begin = server_umount_begin, /* umount -f */ + .statfs = server_statfs, }; +#define log2(n) ffz(~(n)) +#define LUSTRE_SUPER_MAGIC 0x0BD00BD1 + static int server_fill_super_common(struct super_block *sb) { struct inode *root = 0; @@ -1317,20 +1406,20 @@ static void lmd_print(struct lustre_mount_data *lmd) { int i; - CDEBUG(D_MOUNT, "mount data\n"); + LCONSOLE_WARN(" mount data:\n"); if (!lmd->lmd_mgsnid_count) - CDEBUG(D_MOUNT, "no MGS nids\n"); + LCONSOLE_WARN("no MGS nids\n"); else for (i = 0; i < lmd->lmd_mgsnid_count; i++) { - CDEBUG(D_MOUNT, "nid %d: %s\n", i, + LCONSOLE_WARN("nid %d: %s\n", i, libcfs_nid2str(lmd->lmd_mgsnid[i])); } if (lmd_is_client(lmd)) - CDEBUG(D_MOUNT, "fsname: %s\n", lmd->lmd_dev); + LCONSOLE_WARN("fsname: %s\n", lmd->lmd_dev); else - CDEBUG(D_MOUNT, "device: %s\n", lmd->lmd_dev); - CDEBUG(D_MOUNT, "flags: %x\n", lmd->lmd_flags); + LCONSOLE_WARN("device: %s\n", lmd->lmd_dev); + LCONSOLE_WARN("flags: %x\n", lmd->lmd_flags); if (lmd->lmd_opts) - CDEBUG(D_MOUNT, "options: %s\n", lmd->lmd_opts); + LCONSOLE_WARN("options: %s\n", lmd->lmd_opts); } static int lmd_parse(char *options, struct lustre_mount_data *lmd) @@ -1570,8 +1659,10 @@ int lustre_unregister_fs(void) EXPORT_SYMBOL(lustre_register_client_fill_super); EXPORT_SYMBOL(lustre_common_put_super); -EXPORT_SYMBOL(lustre_get_process_log); +EXPORT_SYMBOL(config_log_start); +EXPORT_SYMBOL(config_log_end); +EXPORT_SYMBOL(config_log_get); +EXPORT_SYMBOL(config_log_put); EXPORT_SYMBOL(server_get_mount); EXPORT_SYMBOL(server_put_mount); - diff --git a/lustre/utils/llog_reader.c b/lustre/utils/llog_reader.c index 4ea9996..7141919 100644 --- a/lustre/utils/llog_reader.c +++ b/lustre/utils/llog_reader.c @@ -325,8 +325,9 @@ void print_lustre_cfg(struct lustre_cfg *lcfg) break; } case(LCFG_MARKER):{ - printf("marker "); - print_1_cfg(lcfg); + struct cfg_marker *marker = lustre_cfg_buf(lcfg, 1); + printf("marker %d (flags=%#x) '%s'", marker->cm_step, + marker->cm_flags, marker->cm_comment); break; } default: