Some in memory data may be released/uninitialized at the time
of proc entry creation/removal, this patch includes the following
fixes:
* initialize data before proc entry creation
* free data after proc entry removal
* free proc entries in obd_precleanup() because
obd_uuid/nid/nid_stats_hash are released in class_cleanup().
* free proc entries after obd_zombie_barrier() because obd_export
hold one refcound of nid_stat.
* check osd->od_mount before accessing osd proc entries because the
osd proc entries are created before mount.
Signed-off-by: Lai Siyao <laisiyao@whamcloud.com>
Change-Id: I03cb977e1be0747032a70f6a39fec804f81d70cc
Reviewed-on: http://review.whamcloud.com/326
Tested-by: Hudson
Reviewed-by: Johann Lombardi <johann@whamcloud.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
15 files changed:
}
cfs_spin_unlock(&cm->cmm_tgt_guard);
}
cfs_spin_unlock(&cm->cmm_tgt_guard);
+ fld_client_proc_fini(cm->cmm_fld);
fld_client_fini(cm->cmm_fld);
ls = cmm2lu_dev(cm)->ld_site;
lu_site2md(ls)->ms_client_fld = NULL;
fld_client_fini(cm->cmm_fld);
ls = cmm2lu_dev(cm)->ld_site;
lu_site2md(ls)->ms_client_fld = NULL;
}
EXPORT_SYMBOL(fld_client_del_target);
}
EXPORT_SYMBOL(fld_client_del_target);
-static void fld_client_proc_fini(struct lu_client_fld *fld);
-
#ifdef LPROCFS
static int fld_client_proc_init(struct lu_client_fld *fld)
{
#ifdef LPROCFS
static int fld_client_proc_init(struct lu_client_fld *fld)
{
-static void fld_client_proc_fini(struct lu_client_fld *fld)
+void fld_client_proc_fini(struct lu_client_fld *fld)
{
ENTRY;
if (fld->lcf_proc_dir) {
{
ENTRY;
if (fld->lcf_proc_dir) {
-static void fld_client_proc_fini(struct lu_client_fld *fld)
+void fld_client_proc_fini(struct lu_client_fld *fld)
+EXPORT_SYMBOL(fld_client_proc_fini);
+
static inline int hash_is_sane(int hash)
{
return (hash >= 0 && hash < ARRAY_SIZE(fld_hash));
static inline int hash_is_sane(int hash)
{
return (hash >= 0 && hash < ARRAY_SIZE(fld_hash));
struct lu_fld_target *target, *tmp;
ENTRY;
struct lu_fld_target *target, *tmp;
ENTRY;
- fld_client_proc_fini(fld);
-
cfs_spin_lock(&fld->lcf_lock);
cfs_list_for_each_entry_safe(target, tmp,
&fld->lcf_targets, ft_chain) {
cfs_spin_lock(&fld->lcf_lock);
cfs_list_for_each_entry_safe(target, tmp,
&fld->lcf_targets, ft_chain) {
extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list);
extern int lprocfs_obd_cleanup(struct obd_device *obd);
extern int lprocfs_obd_setup(struct obd_device *obd, struct lprocfs_vars *list);
extern int lprocfs_obd_cleanup(struct obd_device *obd);
-extern void lprocfs_free_per_client_stats(struct obd_device *obd);
extern struct file_operations lprocfs_evict_client_fops;
extern int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name,
extern struct file_operations lprocfs_evict_client_fops;
extern int lprocfs_seq_create(cfs_proc_dir_entry_t *parent, char *name,
int fld_client_del_target(struct lu_client_fld *fld,
__u64 idx);
int fld_client_del_target(struct lu_client_fld *fld,
__u64 idx);
+void fld_client_proc_fini(struct lu_client_fld *fld);
+
ENTRY;
fld_client_fini(&lmv->lmv_fld);
ENTRY;
fld_client_fini(&lmv->lmv_fld);
- lprocfs_obd_cleanup(obd);
lmv_object_cleanup(obd);
OBD_FREE(lmv->datas, lmv->datas_size);
OBD_FREE(lmv->tgts, lmv->tgts_size);
lmv_object_cleanup(obd);
OBD_FREE(lmv->datas, lmv->datas_size);
OBD_FREE(lmv->tgts, lmv->tgts_size);
static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
{
static int lmv_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
{
+ struct lmv_obd *lmv = &obd->u.lmv;
+ int rc = 0;
switch (stage) {
case OBD_CLEANUP_EARLY:
switch (stage) {
case OBD_CLEANUP_EARLY:
* stack. */
break;
case OBD_CLEANUP_EXPORTS:
* stack. */
break;
case OBD_CLEANUP_EXPORTS:
+ fld_client_proc_fini(&lmv->lmv_fld);
+ lprocfs_obd_cleanup(obd);
rc = obd_llog_finish(obd, 0);
if (rc != 0)
CERROR("failed to cleanup llogging subsystems\n");
rc = obd_llog_finish(obd, 0);
if (rc != 0)
CERROR("failed to cleanup llogging subsystems\n");
break;
}
case OBD_CLEANUP_EXPORTS:
break;
}
case OBD_CLEANUP_EXPORTS:
+ lprocfs_obd_cleanup(obd);
rc = obd_llog_finish(obd, 0);
if (rc != 0)
CERROR("failed to cleanup llogging subsystems\n");
rc = obd_llog_finish(obd, 0);
if (rc != 0)
CERROR("failed to cleanup llogging subsystems\n");
struct lov_obd *lov = &obd->u.lov;
cfs_list_t *pos, *tmp;
struct pool_desc *pool;
struct lov_obd *lov = &obd->u.lov;
cfs_list_t *pos, *tmp;
struct pool_desc *pool;
cfs_list_for_each_safe(pos, tmp, &lov->lov_pool_list) {
pool = cfs_list_entry(pos, struct pool_desc, pool_list);
cfs_list_for_each_safe(pos, tmp, &lov->lov_pool_list) {
pool = cfs_list_entry(pos, struct pool_desc, pool_list);
lov->lov_tgt_size);
lov->lov_tgt_size = 0;
}
lov->lov_tgt_size);
lov->lov_tgt_size = 0;
}
-
- /* clear pools parent proc entry only after all pools is killed */
- lprocfs_obd_cleanup(obd);
-
OBD_FREE_PTR(lov->lov_qos.lq_statfs_data);
RETURN(0);
}
OBD_FREE_PTR(lov->lov_qos.lq_statfs_data);
RETURN(0);
}
libcfs_kkuc_group_rem(0, KUC_GRP_HSM);
obd_cleanup_client_import(obd);
libcfs_kkuc_group_rem(0, KUC_GRP_HSM);
obd_cleanup_client_import(obd);
+ ptlrpc_lprocfs_unregister_obd(obd);
+ lprocfs_obd_cleanup(obd);
rc = obd_llog_finish(obd, 0);
if (rc != 0)
rc = obd_llog_finish(obd, 0);
if (rc != 0)
OBD_FREE(cli->cl_setattr_lock, sizeof (*cli->cl_setattr_lock));
OBD_FREE(cli->cl_close_lock, sizeof (*cli->cl_close_lock));
OBD_FREE(cli->cl_setattr_lock, sizeof (*cli->cl_setattr_lock));
OBD_FREE(cli->cl_close_lock, sizeof (*cli->cl_close_lock));
- ptlrpc_lprocfs_unregister_obd(obd);
- lprocfs_obd_cleanup(obd);
ptlrpcd_decref();
return client_obd_cleanup(obd);
ptlrpcd_decref();
return client_obd_cleanup(obd);
mdt_obd_llog_cleanup(obd);
obd_exports_barrier(obd);
obd_zombie_barrier();
mdt_obd_llog_cleanup(obd);
obd_exports_barrier(obd);
obd_zombie_barrier();
+
+ mdt_procfs_fini(m);
+
#ifdef HAVE_QUOTA_SUPPORT
next->md_ops->mdo_quota.mqo_cleanup(env, next);
#endif
#ifdef HAVE_QUOTA_SUPPORT
next->md_ops->mdo_quota.mqo_cleanup(env, next);
#endif
*/
mdt_stack_fini(env, m, md2lu_dev(m->mdt_child));
*/
mdt_stack_fini(env, m, md2lu_dev(m->mdt_child));
- lprocfs_free_per_client_stats(obd);
- lprocfs_free_obd_stats(obd);
- mdt_procfs_fini(m);
-
if (ls) {
struct md_site *mite;
if (ls) {
struct md_site *mite;
GOTO(err_free_site, rc);
}
GOTO(err_free_site, rc);
}
- rc = mdt_procfs_init(m, dev);
- if (rc) {
- CERROR("Can't init MDT lprocfs, rc %d\n", rc);
- GOTO(err_fini_proc, rc);
- }
-
/* set server index */
lu_site2md(s)->ms_node_id = node_id;
/* set server index */
lu_site2md(s)->ms_node_id = node_id;
rc = mdt_stack_init((struct lu_env *)env, m, cfg, lmi);
if (rc) {
CERROR("Can't init device stack, rc %d\n", rc);
rc = mdt_stack_init((struct lu_env *)env, m, cfg, lmi);
if (rc) {
CERROR("Can't init device stack, rc %d\n", rc);
- GOTO(err_fini_proc, rc);
}
rc = lut_init(env, &m->mdt_lut, obd, m->mdt_bottom);
}
rc = lut_init(env, &m->mdt_lut, obd, m->mdt_bottom);
target_recovery_init(&m->mdt_lut, mdt_recovery_handle);
target_recovery_init(&m->mdt_lut, mdt_recovery_handle);
+ rc = mdt_procfs_init(m, dev);
+ if (rc) {
+ CERROR("Can't init MDT lprocfs, rc %d\n", rc);
+ GOTO(err_recovery, rc);
+ }
+
rc = mdt_start_ptlrpc_service(m);
if (rc)
rc = mdt_start_ptlrpc_service(m);
if (rc)
- GOTO(err_recovery, rc);
err_stop_service:
ping_evictor_stop();
mdt_stop_ptlrpc_service(m);
err_stop_service:
ping_evictor_stop();
mdt_stop_ptlrpc_service(m);
+err_procfs:
+ mdt_procfs_fini(m);
err_recovery:
target_recovery_fini(obd);
upcall_cache_cleanup(m->mdt_identity_cache);
err_recovery:
target_recovery_fini(obd);
upcall_cache_cleanup(m->mdt_identity_cache);
lut_fini(env, &m->mdt_lut);
err_fini_stack:
mdt_stack_fini(env, m, md2lu_dev(m->mdt_child));
lut_fini(env, &m->mdt_lut);
err_fini_stack:
mdt_stack_fini(env, m, md2lu_dev(m->mdt_child));
-err_fini_proc:
- mdt_procfs_fini(m);
lu_site_fini(s);
err_free_site:
OBD_FREE_PTR(mite);
lu_site_fini(s);
err_free_site:
OBD_FREE_PTR(mite);
struct lu_device *ld = &mdt->mdt_md_dev.md_lu_dev;
struct obd_device *obd = ld->ld_obd;
struct lu_device *ld = &mdt->mdt_md_dev.md_lu_dev;
struct obd_device *obd = ld->ld_obd;
- if (mdt->mdt_proc_entry) {
- lu_time_fini(&ld->ld_site->ls_time_stats);
- lu_time_fini(&mdt->mdt_stats);
- mdt->mdt_proc_entry = NULL;
- }
if (obd->obd_proc_exports_entry) {
lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
obd->obd_proc_exports_entry = NULL;
}
if (obd->obd_proc_exports_entry) {
lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
obd->obd_proc_exports_entry = NULL;
}
+ lprocfs_free_per_client_stats(obd);
+ lprocfs_obd_cleanup(obd);
ptlrpc_lprocfs_unregister_obd(obd);
ptlrpc_lprocfs_unregister_obd(obd);
+ if (mdt->mdt_proc_entry) {
+ lu_time_fini(&ld->ld_site->ls_time_stats);
+ lu_time_fini(&mdt->mdt_stats);
+ mdt->mdt_proc_entry = NULL;
+ }
lprocfs_free_md_stats(obd);
lprocfs_free_md_stats(obd);
- lprocfs_obd_cleanup(obd);
+ lprocfs_free_obd_stats(obd);
{
struct obd_device *obd = data;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
{
struct obd_device *obd = data;
struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
return snprintf(page, count, "%u:%u\n", mdt->mdt_squash_uid,
mdt->mdt_squash_gid);
return snprintf(page, count, "%u:%u\n", mdt->mdt_squash_uid,
mdt->mdt_squash_gid);
static int mgs_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
{
static int mgs_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
{
+ struct mgs_obd *mgs = &obd->u.mgs;
int rc = 0;
ENTRY;
switch (stage) {
case OBD_CLEANUP_EARLY:
int rc = 0;
ENTRY;
switch (stage) {
case OBD_CLEANUP_EARLY:
case OBD_CLEANUP_EXPORTS:
case OBD_CLEANUP_EXPORTS:
+ ping_evictor_stop();
+ ptlrpc_unregister_service(mgs->mgs_service);
+ mgs_cleanup_fsdb_list(obd);
rc = obd_llog_finish(obd, 0);
rc = obd_llog_finish(obd, 0);
+ lproc_mgs_cleanup(obd);
if (mgs->mgs_sb == NULL)
RETURN(0);
if (mgs->mgs_sb == NULL)
RETURN(0);
- ping_evictor_stop();
-
- ptlrpc_unregister_service(mgs->mgs_service);
-
- mgs_cleanup_fsdb_list(obd);
- lproc_mgs_cleanup(obd);
mgs_fs_cleanup(obd);
server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
mgs_fs_cleanup(obd);
server_put_mount(obd->obd_name, mgs->mgs_vfsmnt);
"nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
atomic_read(&client_stat->nid_exp_ref_count));
"nid %s:count %d\n", libcfs_nid2str(client_stat->nid),
atomic_read(&client_stat->nid_exp_ref_count));
- cfs_hlist_del_init(&client_stat->nid_hash);
-
if (client_stat->nid_proc)
lprocfs_remove(&client_stat->nid_proc);
if (client_stat->nid_proc)
lprocfs_remove(&client_stat->nid_proc);
void lprocfs_free_per_client_stats(struct obd_device *obd)
{
void lprocfs_free_per_client_stats(struct obd_device *obd)
{
+ cfs_hash_t *hash = obd->obd_nid_stats_hash;
struct nid_stat *stat;
ENTRY;
/* we need extra list - because hash_exit called to early */
/* not need locking because all clients is died */
struct nid_stat *stat;
ENTRY;
/* we need extra list - because hash_exit called to early */
/* not need locking because all clients is died */
- while(!cfs_list_empty(&obd->obd_nid_stats)) {
+ while (!cfs_list_empty(&obd->obd_nid_stats)) {
stat = cfs_list_entry(obd->obd_nid_stats.next,
struct nid_stat, nid_list);
cfs_list_del_init(&stat->nid_list);
stat = cfs_list_entry(obd->obd_nid_stats.next,
struct nid_stat, nid_list);
cfs_list_del_init(&stat->nid_list);
+ cfs_hash_del(hash, &stat->nid, &stat->nid_hash);
lprocfs_free_client_stats(stat);
}
lprocfs_free_client_stats(stat);
}
}
EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
}
EXPORT_SYMBOL(lprocfs_nid_stats_clear_read);
-int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
+static int lprocfs_nid_stats_clear_write_cb(void *obj, void *data)
{
struct nid_stat *stat = obj;
int i;
{
struct nid_stat *stat = obj;
int i;
class_disconnect_exports(obd);
}
class_disconnect_exports(obd);
}
+ /* Precleanup, we must make sure all exports get destroyed. */
+ err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
+ if (err)
+ CERROR("Precleanup %s returned %d\n",
+ obd->obd_name, err);
+
/* destroy an uuid-export hash body */
if (obd->obd_uuid_hash) {
cfs_hash_putref(obd->obd_uuid_hash);
/* destroy an uuid-export hash body */
if (obd->obd_uuid_hash) {
cfs_hash_putref(obd->obd_uuid_hash);
obd->obd_nid_stats_hash = NULL;
}
obd->obd_nid_stats_hash = NULL;
}
- /* Precleanup, we must make sure all exports get destroyed. */
- err = obd_precleanup(obd, OBD_CLEANUP_EXPORTS);
- if (err)
- CERROR("Precleanup %s returned %d\n",
- obd->obd_name, err);
class_decref(obd, "setup", obd);
obd->obd_set_up = 0;
class_decref(obd, "setup", obd);
obd->obd_set_up = 0;
case OBD_CLEANUP_EXPORTS:
/* Stop recovery before namespace cleanup. */
target_recovery_fini(obd);
case OBD_CLEANUP_EXPORTS:
/* Stop recovery before namespace cleanup. */
target_recovery_fini(obd);
+
+ obd_exports_barrier(obd);
+ obd_zombie_barrier();
+
rc = filter_llog_preclean(obd);
rc = filter_llog_preclean(obd);
+ lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
+ lprocfs_free_per_client_stats(obd);
+ lprocfs_obd_cleanup(obd);
+ lprocfs_free_obd_stats(obd);
+ lquota_cleanup(filter_quota_interface_ref, obd);
LCONSOLE_WARN("%s: shutting down for failover; client state "
"will be preserved.\n", obd->obd_name);
LCONSOLE_WARN("%s: shutting down for failover; client state "
"will be preserved.\n", obd->obd_name);
- obd_exports_barrier(obd);
- obd_zombie_barrier();
-
- lprocfs_remove_proc_entry("clear", obd->obd_proc_exports_entry);
- lprocfs_free_per_client_stats(obd);
- lprocfs_free_obd_stats(obd);
- lprocfs_obd_cleanup(obd);
- lquota_cleanup(filter_quota_interface_ref, obd);
-
ldlm_namespace_free(obd->obd_namespace, NULL, obd->obd_force);
obd->obd_namespace = NULL;
ldlm_namespace_free(obd->obd_namespace, NULL, obd->obd_force);
obd->obd_namespace = NULL;
*/
obd_zombie_barrier();
obd_cleanup_client_import(obd);
*/
obd_zombie_barrier();
obd_cleanup_client_import(obd);
+ ptlrpc_lprocfs_unregister_obd(obd);
+ lprocfs_obd_cleanup(obd);
rc = obd_llog_finish(obd, 0);
if (rc != 0)
CERROR("failed to cleanup llogging subsystems\n");
rc = obd_llog_finish(obd, 0);
if (rc != 0)
CERROR("failed to cleanup llogging subsystems\n");
- ptlrpc_lprocfs_unregister_obd(obd);
- lprocfs_obd_cleanup(obd);
/* free memory of osc quota cache */
lquota_cleanup(quota_interface, obd);
/* free memory of osc quota cache */
lquota_cleanup(quota_interface, obd);
int *eof, void *data)
{
struct osd_device *osd = data;
int *eof, void *data)
{
struct osd_device *osd = data;
- int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ int rc;
+
+ if (unlikely(osd->od_mount == NULL))
+ return -EINPROGRESS;
+
+ rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
if (!rc) {
*eof = 1;
rc = snprintf(page, count, "%ld\n", osd->od_kstatfs.f_bsize);
if (!rc) {
*eof = 1;
rc = snprintf(page, count, "%ld\n", osd->od_kstatfs.f_bsize);
int *eof, void *data)
{
struct osd_device *osd = data;
int *eof, void *data)
{
struct osd_device *osd = data;
- int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ int rc;
+
+ if (unlikely(osd->od_mount == NULL))
+ return -EINPROGRESS;
+
+ rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
if (!rc) {
__u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
__u64 result = osd->od_kstatfs.f_blocks;
if (!rc) {
__u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
__u64 result = osd->od_kstatfs.f_blocks;
int *eof, void *data)
{
struct osd_device *osd = data;
int *eof, void *data)
{
struct osd_device *osd = data;
- int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ int rc;
+
+ if (unlikely(osd->od_mount == NULL))
+ return -EINPROGRESS;
+
+ rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
if (!rc) {
__u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
__u64 result = osd->od_kstatfs.f_bfree;
if (!rc) {
__u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
__u64 result = osd->od_kstatfs.f_bfree;
int *eof, void *data)
{
struct osd_device *osd = data;
int *eof, void *data)
{
struct osd_device *osd = data;
- int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ int rc;
+
+ if (unlikely(osd->od_mount == NULL))
+ return -EINPROGRESS;
+
+ rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
if (!rc) {
__u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
__u64 result = osd->od_kstatfs.f_bavail;
if (!rc) {
__u32 blk_size = osd->od_kstatfs.f_bsize >> 10;
__u64 result = osd->od_kstatfs.f_bavail;
int *eof, void *data)
{
struct osd_device *osd = data;
int *eof, void *data)
{
struct osd_device *osd = data;
- int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ int rc;
+
+ if (unlikely(osd->od_mount == NULL))
+ return -EINPROGRESS;
+
+ rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
if (!rc) {
*eof = 1;
rc = snprintf(page, count, LPU64"\n", osd->od_kstatfs.f_files);
if (!rc) {
*eof = 1;
rc = snprintf(page, count, LPU64"\n", osd->od_kstatfs.f_files);
int *eof, void *data)
{
struct osd_device *osd = data;
int *eof, void *data)
{
struct osd_device *osd = data;
- int rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
+ int rc;
+
+ if (unlikely(osd->od_mount == NULL))
+ return -EINPROGRESS;
+
+ rc = osd_statfs(NULL, &osd->od_dt_dev, &osd->od_kstatfs);
if (!rc) {
*eof = 1;
rc = snprintf(page, count, LPU64"\n", osd->od_kstatfs.f_ffree);
if (!rc) {
*eof = 1;
rc = snprintf(page, count, LPU64"\n", osd->od_kstatfs.f_ffree);
struct osd_device *osd = data;
LASSERT(osd != NULL);
struct osd_device *osd = data;
LASSERT(osd != NULL);
+ if (unlikely(osd->od_mount == NULL))
+ return -EINPROGRESS;
+
LASSERT(osd->od_mount->lmi_mnt->mnt_devname);
*eof = 1;
LASSERT(osd->od_mount->lmi_mnt->mnt_devname);
*eof = 1;