From 4fdf3b5bc8a4704f74e6f7dd6455b9965dbbead1 Mon Sep 17 00:00:00 2001 From: nikita Date: Fri, 21 Jul 2006 19:25:56 +0000 Subject: [PATCH] updates to lu_object printing code: - print objects into log (libcfs_debug_msg()); - LU_OBJECT_DEBUG() macro. --- lustre/cmm/cmm_object.c | 24 ++-- lustre/cmm/mdc_object.c | 8 +- lustre/include/lu_object.h | 65 ++++++++- lustre/kernel_patches/patches/ext3-iam-uapi.patch | 22 +-- lustre/mdd/mdd_handler.c | 6 +- lustre/mdt/mdt_handler.c | 24 ++-- lustre/obdclass/lu_object.c | 157 ++++++++++++++++++++-- 7 files changed, 249 insertions(+), 57 deletions(-) diff --git a/lustre/cmm/cmm_object.c b/lustre/cmm/cmm_object.c index 0eacde80..02b9b15 100644 --- a/lustre/cmm/cmm_object.c +++ b/lustre/cmm/cmm_object.c @@ -44,9 +44,9 @@ static int cmm_fld_lookup(struct cmm_device *cm, ENTRY; LASSERT(fid_is_sane(fid)); - + ls = cm->cmm_md_dev.md_lu_dev.ld_site; - + rc = fld_client_lookup(ls->ls_client_fld, fid_seq(fid), mds); if (rc) { @@ -196,10 +196,10 @@ static int cml_object_exists(const struct lu_context *ctx, return lu_object_exists(ctx, lu_object_next(lo)); } -static int cml_object_print(const struct lu_context *ctx, - struct seq_file *f, const struct lu_object *lo) +static int cml_object_print(const struct lu_context *ctx, void *cookie, + lu_printer_t p, const struct lu_object *lo) { - return seq_printf(f, LUSTRE_CMM0_NAME"-local@%p", lo); + return (*p)(ctx, cookie, LUSTRE_CMM0_NAME"-local@%p", lo); } static struct lu_object_operations cml_obj_ops = { @@ -314,8 +314,8 @@ static int cml_lookup(const struct lu_context *ctx, struct md_object *mo_p, } -static int cml_create(const struct lu_context *ctx, struct md_object *mo_p, - const char *child_name, struct md_object *mo_c, +static int cml_create(const struct lu_context *ctx, struct md_object *mo_p, + const char *child_name, struct md_object *mo_c, const char *target_name, struct md_attr *ma) { int rc; @@ -479,10 +479,10 @@ static int cmr_object_exists(const struct lu_context *ctx, return -1; } -static int cmr_object_print(const struct lu_context *ctx, - struct seq_file *f, const struct lu_object *lo) +static int cmr_object_print(const struct lu_context *ctx, void *cookie, + lu_printer_t p, const struct lu_object *lo) { - return seq_printf(f, LUSTRE_CMM0_NAME"-remote@%p", lo); + return (*p)(ctx, cookie, LUSTRE_CMM0_NAME"-remote@%p", lo); } static struct lu_object_operations cmr_obj_ops = { @@ -578,7 +578,7 @@ static int cmr_lookup(const struct lu_context *ctx, struct md_object *mo_p, * */ static int cmr_create(const struct lu_context *ctx, struct md_object *mo_p, - const char *child_name, struct md_object *mo_c, + const char *child_name, struct md_object *mo_c, const char *target_name, struct md_attr *ma) { int rc; @@ -653,7 +653,7 @@ static int cmr_rename(const struct lu_context *ctx, struct md_object *mo_po, RETURN(rc); } -/* part of cross-ref rename(). Used to insert new name in new parent +/* part of cross-ref rename(). Used to insert new name in new parent * and unlink target with same name if it exists */ static int cmr_rename_tgt(const struct lu_context *ctx, struct md_object *mo_p, struct md_object *mo_t, diff --git a/lustre/cmm/mdc_object.c b/lustre/cmm/mdc_object.c index b053e8b..f9fcea0 100644 --- a/lustre/cmm/mdc_object.c +++ b/lustre/cmm/mdc_object.c @@ -77,10 +77,10 @@ static int mdc_object_init(const struct lu_context *ctx, struct lu_object *lo) RETURN(0); } -static int mdc_object_print(const struct lu_context *ctx, - struct seq_file *f, const struct lu_object *lo) +static int mdc_object_print(const struct lu_context *ctx, void *cookie, + lu_printer_t p, const struct lu_object *lo) { - return seq_printf(f, LUSTRE_MDC0_NAME"-object@%p", lo); + return (*p)(ctx, cookie, LUSTRE_MDC0_NAME"-object@%p", lo); } static struct lu_object_operations mdc_obj_ops = { @@ -101,7 +101,7 @@ static int mdc_object_create(const struct lu_context *ctx, mci = lu_context_key_get(ctx, &mdc_thread_key); LASSERT(mci); - + memset(&mci->mci_opdata, 0, sizeof(mci->mci_opdata)); mci->mci_opdata.fid1 = *lu_object_fid(&mo->mo_lu); mci->mci_opdata.mod_time = attr->la_mtime; diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index 9cfdc94..5779c8e 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -144,6 +144,16 @@ struct lu_device_operations { }; /* + * Type of "printer" function used by ->loo_object_print() method. + * + * Printer function is needed to provide some flexibility in (semi-)debugging + * output: possible implementations: printk, CDEBUG, sysfs/seq_file + */ +typedef int (*lu_printer_t)(const struct lu_context *ctx, + void *cookie, const char *format, ...) + __attribute__ ((format (printf, 3, 4))); + +/* * Operations specific for particular lu_object. */ struct lu_object_operations { @@ -187,8 +197,8 @@ struct lu_object_operations { /* * Debugging helper. Print given object. */ - int (*loo_object_print)(const struct lu_context *ctx, - struct seq_file *f, const struct lu_object *o); + int (*loo_object_print)(const struct lu_context *ctx, void *cookie, + lu_printer_t p, const struct lu_object *o); /* * Optional debugging method. Returns true iff method is internally * consistent. @@ -435,6 +445,7 @@ struct lu_object_header { }; struct fld; + /* * lu_site is a "compartment" within which objects are unique, and LRU * discipline is maintained. @@ -697,11 +708,41 @@ lu_object_ops(const struct lu_object *o) struct lu_object *lu_object_locate(struct lu_object_header *h, struct lu_device_type *dtype); +struct lu_cdebug_print_info { + int lpi_subsys; + int lpi_mask; + const char *lpi_file; + const char *lpi_fn; + int lpi_line; +}; + +/* + * Printer function emitting messages through libcfs_debug_msg(). + */ +int lu_cdebug_printer(const struct lu_context *ctx, + void *cookie, const char *format, ...); + +/* + * Print object description followed by user-supplied message. + */ +#define LU_OBJECT_DEBUG(mask, ctx, object, format, ...) \ +({ \ + static struct lu_cdebug_print_info __info = { \ + .lpi_subsys = DEBUG_SUBSYSTEM, \ + .lpi_mask = (mask), \ + .lpi_file = __FILE__, \ + .lpi_fn = __FUNCTION__, \ + .lpi_line = __LINE__ \ + }; \ + lu_object_print(ctx, &__info, lu_cdebug_printer, object); \ + CDEBUG(mask, format , ## __VA_ARGS__); \ +}) + /* * Print human readable representation of the @o to the @f. */ -int lu_object_print(const struct lu_context *ctxt, - struct seq_file *f, const struct lu_object *o); +void lu_object_print(const struct lu_context *ctxt, void *cookie, + lu_printer_t printer, const struct lu_object *o); /* * Check object consistency. @@ -710,7 +751,7 @@ int lu_object_invariant(const struct lu_object *o); /* * Returns 1 iff object @o exists on the stable storage, - * returns -1 iif object @o is on remote server. + * returns -1 iff object @o is on remote server. */ static inline int lu_object_exists(const struct lu_context *ctx, const struct lu_object *o) @@ -719,13 +760,13 @@ static inline int lu_object_exists(const struct lu_context *ctx, } static inline int lu_object_assert_exists(const struct lu_context *ctx, - const struct lu_object *o) + const struct lu_object *o) { return lu_object_exists(ctx, o) != 0; } static inline int lu_object_assert_not_exists(const struct lu_context *ctx, - const struct lu_object *o) + const struct lu_object *o) { return lu_object_exists(ctx, o) <= 0; } @@ -848,4 +889,14 @@ void lu_context_enter(struct lu_context *ctx); */ void lu_context_exit(struct lu_context *ctx); +/* + * Initialization of global lu_* data. + */ +int lu_global_init(void); + +/* + * Dual to lu_global_init(). + */ +void lu_global_fini(void); + #endif /* __LUSTRE_LU_OBJECT_H */ diff --git a/lustre/kernel_patches/patches/ext3-iam-uapi.patch b/lustre/kernel_patches/patches/ext3-iam-uapi.patch index f97aaa6..20cc4a7 100644 --- a/lustre/kernel_patches/patches/ext3-iam-uapi.patch +++ b/lustre/kernel_patches/patches/ext3-iam-uapi.patch @@ -1,7 +1,7 @@ Index: iam/fs/ext3/Makefile =================================================================== ---- iam.orig/fs/ext3/Makefile 2006-07-20 18:33:52.000000000 +0400 -+++ iam/fs/ext3/Makefile 2006-07-20 18:33:52.000000000 +0400 +--- iam.orig/fs/ext3/Makefile 2006-07-21 23:12:10.000000000 +0400 ++++ iam/fs/ext3/Makefile 2006-07-21 23:12:10.000000000 +0400 @@ -6,7 +6,7 @@ obj-$(CONFIG_EXT3_FS) += ext3.o ext3-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ @@ -13,8 +13,8 @@ Index: iam/fs/ext3/Makefile ext3-$(CONFIG_EXT3_FS_POSIX_ACL) += acl.o Index: iam/fs/ext3/dir.c =================================================================== ---- iam.orig/fs/ext3/dir.c 2006-07-20 18:33:52.000000000 +0400 -+++ iam/fs/ext3/dir.c 2006-07-20 18:33:52.000000000 +0400 +--- iam.orig/fs/ext3/dir.c 2006-07-21 23:12:10.000000000 +0400 ++++ iam/fs/ext3/dir.c 2006-07-21 23:12:10.000000000 +0400 @@ -28,6 +28,7 @@ #include #include @@ -112,8 +112,8 @@ Index: iam/fs/ext3/dir.c (filp->f_version != inode->i_version)) { Index: iam/fs/ext3/file.c =================================================================== ---- iam.orig/fs/ext3/file.c 2006-07-20 18:33:52.000000000 +0400 -+++ iam/fs/ext3/file.c 2006-07-20 18:33:52.000000000 +0400 +--- iam.orig/fs/ext3/file.c 2006-07-21 23:12:10.000000000 +0400 ++++ iam/fs/ext3/file.c 2006-07-21 23:12:10.000000000 +0400 @@ -23,6 +23,7 @@ #include #include @@ -149,7 +149,7 @@ Index: iam/fs/ext3/file.c Index: iam/fs/ext3/iam-uapi.c =================================================================== --- iam.orig/fs/ext3/iam-uapi.c 2004-04-06 17:27:52.000000000 +0400 -+++ iam/fs/ext3/iam-uapi.c 2006-07-20 18:33:52.000000000 +0400 ++++ iam/fs/ext3/iam-uapi.c 2006-07-21 23:12:10.000000000 +0400 @@ -0,0 +1,361 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: @@ -514,8 +514,8 @@ Index: iam/fs/ext3/iam-uapi.c +} Index: iam/fs/ext3/ioctl.c =================================================================== ---- iam.orig/fs/ext3/ioctl.c 2006-07-20 18:33:52.000000000 +0400 -+++ iam/fs/ext3/ioctl.c 2006-07-20 18:33:52.000000000 +0400 +--- iam.orig/fs/ext3/ioctl.c 2006-07-21 23:12:10.000000000 +0400 ++++ iam/fs/ext3/ioctl.c 2006-07-21 23:12:10.000000000 +0400 @@ -250,6 +250,6 @@ flags_err: @@ -526,8 +526,8 @@ Index: iam/fs/ext3/ioctl.c } Index: iam/include/linux/lustre_iam.h =================================================================== ---- iam.orig/include/linux/lustre_iam.h 2006-07-20 18:33:52.000000000 +0400 -+++ iam/include/linux/lustre_iam.h 2006-07-20 18:33:52.000000000 +0400 +--- iam.orig/include/linux/lustre_iam.h 2006-07-21 23:12:10.000000000 +0400 ++++ iam/include/linux/lustre_iam.h 2006-07-21 23:12:10.000000000 +0400 @@ -30,9 +30,6 @@ #ifndef __LINUX_LUSTRE_IAM_H__ #define __LINUX_LUSTRE_IAM_H__ diff --git a/lustre/mdd/mdd_handler.c b/lustre/mdd/mdd_handler.c index aa00a0a..d588915 100644 --- a/lustre/mdd/mdd_handler.c +++ b/lustre/mdd/mdd_handler.c @@ -218,10 +218,10 @@ static void mdd_txn_param_build(const struct lu_context *ctx, mdd_ctx_info(ctx)->mti_param.tp_credits = opd->mod_credits; } -static int mdd_object_print(const struct lu_context *ctxt, - struct seq_file *f, const struct lu_object *o) +static int mdd_object_print(const struct lu_context *ctxt, void *cookie, + lu_printer_t p, const struct lu_object *o) { - return seq_printf(f, LUSTRE_MDD0_NAME"-object@%p", o); + return (*p)(ctxt, cookie, LUSTRE_MDD0_NAME"-object@%p", o); } static int mdd_object_exists(const struct lu_context *ctx, diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 126a80e..46208ef 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -772,7 +772,7 @@ int fid_lock(struct ldlm_namespace *ns, const struct lu_fid *f, return rc == ELDLM_OK ? 0 : -EIO; } -/* just call ldlm_lock_decref() if decref, +/* just call ldlm_lock_decref() if decref, * else we only call ptlrpc_save_lock() to save this lock in req. * when transaction committed, req will be released and lock will be released */ void fid_unlock(struct ptlrpc_request *req, const struct lu_fid *f, @@ -790,7 +790,7 @@ void fid_unlock(struct ptlrpc_request *req, const struct lu_fid *f, } if (decref) ldlm_lock_decref(lh, mode); - else + else ptlrpc_save_lock(req, lh, mode); } @@ -841,7 +841,7 @@ void mdt_object_unlock(struct mdt_thread_info *info, struct mdt_object *o, ENTRY; if (lustre_handle_is_used(&lh->mlh_lh)) { - fid_unlock(req, mdt_object_fid(o), + fid_unlock(req, mdt_object_fid(o), &lh->mlh_lh, lh->mlh_mode, decref); lh->mlh_lh.cookie = 0; } @@ -2306,10 +2306,10 @@ static void mdt_object_free(const struct lu_context *ctxt, struct lu_object *o) EXIT; } -static int mdt_object_print(const struct lu_context *ctxt, - struct seq_file *f, const struct lu_object *o) +static int mdt_object_print(const struct lu_context *ctxt, void *cookie, + lu_printer_t p, const struct lu_object *o) { - return seq_printf(f, LUSTRE_MDT0_NAME"-object@%p", o); + return (*p)(ctxt, cookie, LUSTRE_MDT0_NAME"-object@%p", o); } int mdt_object_exists(const struct lu_context *ctx, @@ -2671,18 +2671,24 @@ LPROCFS_INIT_VARS(mdt, lprocfs_mdt_module_vars, lprocfs_mdt_obd_vars); static int __init mdt_mod_init(void) { + int result; struct lprocfs_static_vars lvars; mdt_num_threads = MDT_NUM_THREADS; lprocfs_init_vars(mdt, &lvars); - return class_register_type(&mdt_obd_device_ops, NULL, - lvars.module_vars, LUSTRE_MDT0_NAME, - &mdt_device_type); + result = lu_global_init(); + if (result == 0) + result = class_register_type(&mdt_obd_device_ops, NULL, + lvars.module_vars, + LUSTRE_MDT0_NAME, + &mdt_device_type); + return result; } static void __exit mdt_mod_exit(void) { class_unregister_type(LUSTRE_MDT0_NAME); + lu_global_fini(); } diff --git a/lustre/obdclass/lu_object.c b/lustre/obdclass/lu_object.c index 670c17a..95be489 100644 --- a/lustre/obdclass/lu_object.c +++ b/lustre/obdclass/lu_object.c @@ -224,29 +224,136 @@ void lu_site_purge(const struct lu_context *ctx, struct lu_site *s, int nr) EXPORT_SYMBOL(lu_site_purge); /* - * Print human readable representation of the @o to the @f. + * Object printing. + * + * Code below has to jump through certain loops to output object description + * into libcfs_debug_msg-based log. The problem is that lu_object_print() + * composes object description from strings that are parts of _lines_ of + * output (i.e., strings that are not terminated by newline). This doesn't fit + * very well into libcfs_debug_msg() interface that assumes that each message + * supplied to it is a self-contained output line. + * + * To work around this, strings are collected in a temporary buffer + * (implemented as a value of lu_cdebug_key key), until terminating newline + * character is detected. + * + */ + +enum { + /* + * Maximal line size. + * + * XXX overflow is not handled correctly. + */ + LU_CDEBUG_LINE = 256 +}; + +struct lu_cdebug_data { + /* + * Temporary buffer. + */ + char lck_area[LU_CDEBUG_LINE]; +}; + +static void *lu_cdebug_key_init(const struct lu_context *ctx, + struct lu_context_key *key) +{ + struct lu_cdebug_key *value; + + OBD_ALLOC_PTR(value); + if (value == NULL) + value = ERR_PTR(-ENOMEM); + return value; +} + +static void lu_cdebug_key_fini(const struct lu_context *ctx, + struct lu_context_key *key, void *data) +{ + struct lu_cdebug_key *value = data; + OBD_FREE_PTR(value); +} + +/* + * Key, holding temporary buffer. This key is registered very early by + * lu_global_init(). + */ +static struct lu_context_key lu_cdebug_key = { + .lct_tags = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD, + .lct_init = lu_cdebug_key_init, + .lct_fini = lu_cdebug_key_fini +}; + +/* + * Printer function emitting messages through libcfs_debug_msg(). + */ +int lu_cdebug_printer(const struct lu_context *ctx, + void *cookie, const char *format, ...) +{ + struct lu_cdebug_print_info *info = cookie; + struct lu_cdebug_data *key; + int used; + int complete; + va_list args; + + va_start(args, format); + + key = lu_context_key_get(ctx, &lu_cdebug_key); + LASSERT(key != NULL); + + used = strlen(key->lck_area); + complete = format[strlen(format) - 1] == '\n'; + /* + * Append new chunk to the buffer. + */ + vsnprintf(key->lck_area + used, + ARRAY_SIZE(key->lck_area) - used, format, args); + if (complete) { + libcfs_debug_msg(info->lpi_subsys, info->lpi_mask, + info->lpi_file, info->lpi_fn, + info->lpi_line, "%s", key->lck_area); + key->lck_area[0] = 0; + } + va_end(args); + return 0; +} +EXPORT_SYMBOL(lu_cdebug_printer); + +/* + * Print object header. */ -int lu_object_print(const struct lu_context *ctx, - struct seq_file *f, const struct lu_object *o) +static void lu_object_header_print(const struct lu_context *ctx, + void *cookie, lu_printer_t printer, + const struct lu_object_header *hdr) { - static char ruler[] = "........................................"; + (*printer)(ctx, cookie, "header@%p[%#lx, %d, "DFID3"%s%s]", + hdr, hdr->loh_flags, hdr->loh_ref, PFID3(&hdr->loh_fid), + hlist_unhashed(&hdr->loh_hash) ? "" : " hash", + list_empty(&hdr->loh_lru) ? "" : " lru"); +} + +/* + * Print human readable representation of the @o to the @printer. + */ +void lu_object_print(const struct lu_context *ctx, void *cookie, + lu_printer_t printer, const struct lu_object *o) +{ + static const char ruler[] = "........................................"; struct lu_object_header *top; - int nob; int depth; - nob = 0; top = o->lo_header; + lu_object_header_print(ctx, cookie, printer, top); + (*printer)(ctx, cookie, "\n"); list_for_each_entry(o, &top->loh_layers, lo_linkage) { - depth = o->lo_depth; + depth = o->lo_depth + 4; LASSERT(o->lo_ops->loo_object_print != NULL); /* * print `.' @depth times. */ - nob += seq_printf(f, "%*.*s", depth, depth, ruler); - nob += o->lo_ops->loo_object_print(ctx, f, o); - nob += seq_printf(f, "\n"); + (*printer)(ctx, cookie, "%*.*s", depth, depth, ruler); + o->lo_ops->loo_object_print(ctx, cookie, printer, o); + (*printer)(ctx, cookie, "\n"); } - return nob; } EXPORT_SYMBOL(lu_object_print); @@ -714,3 +821,31 @@ void lu_context_exit(struct lu_context *ctx) { } EXPORT_SYMBOL(lu_context_exit); + +/* + * Initialization of global lu_* data. + */ +int lu_global_init(void) +{ + static int initialized = 0; + int result; + + if (!initialized) { + result = lu_context_key_register(&lu_cdebug_key); + initialized = 1; + } else { + CERROR("Double initialization\n"); + result = 0; + } + return result; +} +EXPORT_SYMBOL(lu_global_init); + +/* + * Dual to lu_global_init(). + */ +void lu_global_fini(void) +{ + lu_context_key_degister(&lu_cdebug_key); +} +EXPORT_SYMBOL(lu_global_fini); -- 1.8.3.1