From: yangsheng Date: Tue, 14 Jun 2011 20:12:06 +0000 (+0800) Subject: LU-411 Kernel panic when running conf-sanity on RHEL5/i686 X-Git-Tag: 2.1.0-RC0~47 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=28c4d8388e62a1252c3540ece3c127d3c9ce7148 LU-411 Kernel panic when running conf-sanity on RHEL5/i686 Reduce stack usage to avoid stack overflow on RHEL5/i686 patchless client. Signed-off-by: Yang Sheng Change-Id: I54d3a19734ab089f44f43943b80a2e7ad1f3335f Reviewed-on: http://review.whamcloud.com/950 Tested-by: Hudson Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index e24c644..d4cd526 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -144,8 +144,8 @@ static inline void lprocfs_echo_init_vars(struct lprocfs_static_vars *lvars) /* Passed as data param to class_config_parse_llog */ struct config_llog_instance { - char * cfg_instance; char * cfg_obdname; + char cfg_instance[sizeof(void*) * 2 + 1]; struct super_block *cfg_sb; struct obd_uuid cfg_uuid; int cfg_last_idx; /* for partial llog processing */ diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 297083b..4274240 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -1849,7 +1849,6 @@ llu_fsswop_mount(const char *source, struct lustre_md md; class_uuid_t uuid; struct config_llog_instance cfg = {0, }; - char ll_instance[sizeof(sbi) * 2 + 3]; struct lustre_profile *lprof; char *zconf_mgsnid, *zconf_profile; char *osc = NULL, *mdc = NULL; @@ -1880,10 +1879,9 @@ llu_fsswop_mount(const char *source, /* generate a string unique to this super, let's try the address of the super itself.*/ - snprintf(ll_instance, sizeof(ll_instance), "%p", sbi); + snprintf(cfg.cfg_instance, sizeof(cfg.cfg_instance), "%p", sbi); /* retrive & parse config log */ - cfg.cfg_instance = ll_instance; cfg.cfg_uuid = sbi->ll_sb_uuid; err = liblustre_process_log(&cfg, zconf_mgsnid, zconf_profile, 1); if (err < 0) { @@ -1896,11 +1894,11 @@ llu_fsswop_mount(const char *source, CERROR("No profile found: %s\n", zconf_profile); GOTO(out_free, err = -EINVAL); } - OBD_ALLOC(osc, strlen(lprof->lp_dt) + strlen(ll_instance) + 2); - sprintf(osc, "%s-%s", lprof->lp_dt, ll_instance); + OBD_ALLOC(osc, strlen(lprof->lp_dt) + strlen(cfg.cfg_instance) + 2); + sprintf(osc, "%s-%s", lprof->lp_dt, cfg.cfg_instance); - OBD_ALLOC(mdc, strlen(lprof->lp_md) + strlen(ll_instance) + 2); - sprintf(mdc, "%s-%s", lprof->lp_md, ll_instance); + OBD_ALLOC(mdc, strlen(lprof->lp_md) + strlen(cfg.cfg_instance) + 2); + sprintf(mdc, "%s-%s", lprof->lp_md, cfg.cfg_instance); if (!osc) { CERROR("no osc\n"); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 2aaffd4..fa69404 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -172,7 +172,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, struct ll_sb_info *sbi = ll_s2sbi(sb); struct obd_device *obd; struct obd_capa *oc = NULL; - struct obd_statfs osfs; + struct obd_statfs *osfs = NULL; struct ptlrpc_request *request = NULL; struct obd_connect_data *data = NULL; struct obd_uuid *uuid; @@ -192,6 +192,12 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, if (data == NULL) RETURN(-ENOMEM); + OBD_ALLOC_PTR(osfs); + if (osfs == NULL) { + OBD_FREE_PTR(data); + RETURN(-ENOMEM); + } + if (proc_lustre_fs_root) { err = lprocfs_register_mountpoint(proc_lustre_fs_root, sb, dt, md); @@ -268,7 +274,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, GOTO(out_md, err); } - err = obd_statfs(obd, &osfs, + err = obd_statfs(obd, osfs, cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS), 0); if (err) GOTO(out_md_fid, err); @@ -281,9 +287,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, GOTO(out_md, err); } - LASSERT(osfs.os_bsize); - sb->s_blocksize = osfs.os_bsize; - sb->s_blocksize_bits = log2(osfs.os_bsize); + LASSERT(osfs->os_bsize); + sb->s_blocksize = osfs->os_bsize; + sb->s_blocksize_bits = log2(osfs->os_bsize); sb->s_magic = LL_SUPER_MAGIC; /* for bug 11559. in $LINUX/fs/read_write.c, function do_sendfile(): @@ -299,7 +305,7 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, #else sb->s_maxbytes = PAGE_CACHE_MAXBYTES; #endif - sbi->ll_namelen = osfs.os_namelen; + sbi->ll_namelen = osfs->os_namelen; sbi->ll_max_rw_chunk = LL_DEFAULT_MAX_RW_CHUNK; if ((sbi->ll_flags & LL_SBI_USER_XATTR) && @@ -516,9 +522,6 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, cl_sb_init(sb); sb->s_root = d_alloc_root(root); - if (data != NULL) - OBD_FREE(data, sizeof(*data)); - sb->s_root->d_op = &ll_d_root_ops; sbi->ll_sdev_orig = sb->s_dev; @@ -533,6 +536,11 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, sb->s_dev = get_uuid2int(uuid->uuid, strlen(uuid->uuid)); sbi->ll_mnt = mnt; + if (data != NULL) + OBD_FREE_PTR(data); + if (osfs != NULL) + OBD_FREE_PTR(osfs); + RETURN(err); out_root: if (root) @@ -550,6 +558,8 @@ out_md: out: if (data != NULL) OBD_FREE_PTR(data); + if (osfs != NULL) + OBD_FREE_PTR(osfs); lprocfs_unregister_mountpoint(sbi); return err; } @@ -865,19 +875,23 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) struct ll_sb_info *sbi; char *dt = NULL, *md = NULL; char *profilenm = get_profile_name(sb); - struct config_llog_instance cfg = {0, }; - char ll_instance[sizeof(sb) * 2 + 1]; + struct config_llog_instance *cfg; int err; ENTRY; CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb); + OBD_ALLOC_PTR(cfg); + if (cfg == NULL) + RETURN(-ENOMEM); + cfs_module_get(); /* client additional sb info */ lsi->lsi_llsbi = sbi = ll_init_sbi(); if (!sbi) { cfs_module_put(THIS_MODULE); + OBD_FREE_PTR(cfg); RETURN(-ENOMEM); } @@ -901,12 +915,11 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) /* Generate a string unique to this super, in case some joker tries to mount the same fs at two mount points. Use the address of the super itself.*/ - sprintf(ll_instance, "%p", sb); - cfg.cfg_instance = ll_instance; - cfg.cfg_uuid = lsi->lsi_llsbi->ll_sb_uuid; + snprintf(cfg->cfg_instance, sizeof(cfg->cfg_instance), "%p", sb); + cfg->cfg_uuid = lsi->lsi_llsbi->ll_sb_uuid; /* set up client obds */ - err = lustre_process_log(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); @@ -924,16 +937,16 @@ int ll_fill_super(struct super_block *sb, struct vfsmount *mnt) lprof->lp_md, lprof->lp_dt); OBD_ALLOC(dt, strlen(lprof->lp_dt) + - strlen(ll_instance) + 2); + strlen(cfg->cfg_instance) + 2); if (!dt) GOTO(out_free, err = -ENOMEM); - sprintf(dt, "%s-%s", lprof->lp_dt, ll_instance); + sprintf(dt, "%s-%s", lprof->lp_dt, cfg->cfg_instance); OBD_ALLOC(md, strlen(lprof->lp_md) + - strlen(ll_instance) + 2); + strlen(cfg->cfg_instance) + 2); if (!md) GOTO(out_free, err = -ENOMEM); - sprintf(md, "%s-%s", lprof->lp_md, ll_instance); + sprintf(md, "%s-%s", lprof->lp_md, cfg->cfg_instance); /* connections, registrations, sb setup */ err = client_common_fill_super(sb, md, dt, mnt); @@ -948,6 +961,7 @@ out_free: else LCONSOLE_WARN("Client %s has started\n", profilenm); + OBD_FREE_PTR(cfg); RETURN(err); } /* ll_fill_super */ @@ -957,7 +971,6 @@ void lu_context_keys_dump(void); 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); struct ll_sb_info *sbi = ll_s2sbi(sb); @@ -969,8 +982,7 @@ void ll_put_super(struct super_block *sb) ll_print_capa_stat(sbi); - sprintf(ll_instance, "%p", sb); - cfg.cfg_instance = ll_instance; + snprintf(cfg.cfg_instance, sizeof(cfg.cfg_instance), "%p", sb); lustre_end_log(sb, NULL, &cfg); if (sbi->ll_md_exp) { @@ -1014,7 +1026,7 @@ void ll_put_super(struct super_block *sb) cl_env_cache_purge(~0); - LCONSOLE_WARN("client %s umount complete\n", ll_instance); + LCONSOLE_WARN("client %s umount complete\n", cfg.cfg_instance); cfs_module_put(THIS_MODULE); diff --git a/lustre/mgc/mgc_request.c b/lustre/mgc/mgc_request.c index bc1cc5f..b4795bd 100644 --- a/lustre/mgc/mgc_request.c +++ b/lustre/mgc/mgc_request.c @@ -146,9 +146,6 @@ static void config_log_put(struct config_llog_data *cld) class_export_put(cld->cld_mgcexp); 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); OBD_FREE(cld, sizeof(*cld)); } else { cfs_spin_unlock(&config_list_lock); @@ -164,13 +161,11 @@ struct config_llog_data *config_log_find(char *logname, { struct config_llog_data *cld; char *logid = logname; - int match_instance = 0; ENTRY; - if (cfg && cfg->cfg_instance) { - match_instance++; + if (cfg) logid = cfg->cfg_instance; - } + if (!logid) { CERROR("No log specified\n"); RETURN(ERR_PTR(-EINVAL)); @@ -178,11 +173,10 @@ struct config_llog_data *config_log_find(char *logname, cfs_spin_lock(&config_list_lock); cfs_list_for_each_entry(cld, &config_llog_list, cld_list_chain) { - if (match_instance && cld->cld_cfg.cfg_instance && - strcmp(logid, cld->cld_cfg.cfg_instance) == 0) - goto out_found; - if (!match_instance && - strcmp(logid, cld->cld_logname) == 0) + char *name = cld->cld_logname; + if (cfg) + name = cld->cld_cfg.cfg_instance; + if (strcmp(logid, name) == 0) goto out_found; } cfs_spin_unlock(&config_list_lock); @@ -231,12 +225,6 @@ struct config_llog_data *do_config_log_add(struct obd_device *obd, /* Keep the mgc around until we are done */ cld->cld_mgcexp = class_export_get(obd->obd_self_export); - if (cfg && 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); - } - if (is_sptlrpc) { sptlrpc_conf_log_start(logname); cld->cld_cfg.cfg_obdname = obd->obd_name; @@ -1257,7 +1245,7 @@ int mgc_process_log(struct obd_device *mgc, struct llog_ctxt *ctxt, *lctxt; struct lustre_handle lockh; struct client_obd *cli = &mgc->u.cli; - struct lvfs_run_ctxt saved; + struct lvfs_run_ctxt *saved_ctxt; struct lustre_sb_info *lsi = NULL; int rc = 0, rcl, flags = 0, must_pop = 0; ENTRY; @@ -1290,6 +1278,12 @@ int mgc_process_log(struct obd_device *mgc, RETURN(-EINVAL); } + OBD_ALLOC_PTR(saved_ctxt); + if (saved_ctxt == NULL) { + cfs_mutex_unlock(&cld->cld_lock); + RETURN(-ENOMEM); + } + /* 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, @@ -1311,7 +1305,7 @@ int mgc_process_log(struct obd_device *mgc, 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); + push_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL); must_pop++; if (rcl == 0) /* Only try to copy log if we have the lock. */ @@ -1347,8 +1341,9 @@ out_pop: if (ctxt != lctxt) llog_ctxt_put(lctxt); if (must_pop) - pop_ctxt(&saved, &mgc->obd_lvfs_ctxt, NULL); + pop_ctxt(saved_ctxt, &mgc->obd_lvfs_ctxt, NULL); + OBD_FREE_PTR(saved_ctxt); /* * update settings on existing OBDs. doing it inside * of llog_process_lock so no device is attaching/detaching @@ -1385,11 +1380,12 @@ out_pop: static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf) { struct lustre_cfg *lcfg = buf; - int cmd; + struct config_llog_instance *cfg = NULL; + char *logname; int rc = 0; ENTRY; - switch(cmd = lcfg->lcfg_command) { + switch(lcfg->lcfg_command) { case LCFG_LOV_ADD_OBD: { /* Overloading this cfg command: register a new target */ struct mgs_target_info *mti; @@ -1415,9 +1411,9 @@ static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf) } 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); + + 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); @@ -1445,8 +1441,8 @@ static int mgc_process_config(struct obd_device *obd, obd_count len, void *buf) break; } case LCFG_LOG_END: { - struct config_llog_instance *cfg = NULL; - char *logname = lustre_cfg_string(lcfg, 1); + logname = lustre_cfg_string(lcfg, 1); + if (lcfg->lcfg_bufcount >= 2) cfg = (struct config_llog_instance *)lustre_cfg_buf( lcfg, 2); diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index 7331460..a9669fa 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -1237,7 +1237,7 @@ static int class_config_llog_handler(struct llog_handle * handle, (lcfg->lcfg_command != LCFG_MARKER)) { CWARN("Config not inside markers, ignoring! " "(inst: %s, uuid: %s, flags: %#x)\n", - clli->cfg_instance ? clli->cfg_instance : "", + clli->cfg_instance, clli->cfg_uuid.uuid, clli->cfg_flags); clli->cfg_flags |= CFG_F_SKIP; } @@ -1279,7 +1279,7 @@ static int class_config_llog_handler(struct llog_handle * handle, lustre_cfg_bufs_init(&bufs, lcfg); - if (clli && clli->cfg_instance && + if (clli && clli->cfg_instance[0] != '\0' && LUSTRE_CFG_BUFLEN(lcfg, 0) > 0){ inst = 1; inst_len = LUSTRE_CFG_BUFLEN(lcfg, 0) + @@ -1297,7 +1297,7 @@ static int class_config_llog_handler(struct llog_handle * handle, /* we override the llog's uuid for clients, to insure they are unique */ - if (clli && clli->cfg_instance && + if (clli && clli->cfg_instance[0] != '\0' && lcfg->lcfg_command == LCFG_ATTACH) { lustre_cfg_bufs_set_string(&bufs, 2, clli->cfg_uuid.uuid); @@ -1309,7 +1309,7 @@ static int class_config_llog_handler(struct llog_handle * handle, * moving them to index [1] and [2], and insert MGC's * obdname at index [0]. */ - if (clli && clli->cfg_instance == NULL && + if (clli && clli->cfg_instance[0] == '\0' && lcfg->lcfg_command == LCFG_SPTLRPC_CONF) { lustre_cfg_bufs_set(&bufs, 2, bufs.lcfg_buf[1], bufs.lcfg_buflen[1]); diff --git a/lustre/obdclass/obd_mount.c b/lustre/obdclass/obd_mount.c index e92d1c2..6ab0f99 100644 --- a/lustre/obdclass/obd_mount.c +++ b/lustre/obdclass/obd_mount.c @@ -394,7 +394,7 @@ int lustre_process_log(struct super_block *sb, char *logname, struct config_llog_instance *cfg) { struct lustre_cfg *lcfg; - struct lustre_cfg_bufs bufs; + struct lustre_cfg_bufs *bufs; struct lustre_sb_info *lsi = s2lsi(sb); struct obd_device *mgc = lsi->lsi_mgc; int rc; @@ -403,15 +403,21 @@ int lustre_process_log(struct super_block *sb, char *logname, LASSERT(mgc); LASSERT(cfg); + OBD_ALLOC_PTR(bufs); + if (bufs == NULL) + RETURN(-ENOMEM); + /* 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)); - lustre_cfg_bufs_set(&bufs, 3, &sb, sizeof(sb)); - lcfg = lustre_cfg_new(LCFG_LOG_START, &bufs); + 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)); + lustre_cfg_bufs_set(bufs, 3, &sb, sizeof(sb)); + lcfg = lustre_cfg_new(LCFG_LOG_START, bufs); rc = obd_process_config(mgc, sizeof(*lcfg), lcfg); lustre_cfg_free(lcfg); + OBD_FREE_PTR(bufs); + if (rc == -EINVAL) LCONSOLE_ERROR_MSG(0x15b, "%s: The configuration from log '%s'" "failed from the MGS (%d). Make sure this "