X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flod%2Flproc_lod.c;h=f9f84c00afe94a0763bab149f0d49dd9bc7395f0;hb=755c04eba3f52245ecddd5c0d7a205988181d7d1;hp=ec67275f05d4f6aa61766051e7ed1337c4c24aef;hpb=2fbf36f5e3890d8b560b5682931999f229021b2d;p=fs%2Flustre-release.git diff --git a/lustre/lod/lproc_lod.c b/lustre/lod/lproc_lod.c index ec67275..f9f84c0 100644 --- a/lustre/lod/lproc_lod.c +++ b/lustre/lod/lproc_lod.c @@ -27,7 +27,7 @@ * Copyright 2008 Sun Microsystems, Inc. All rights reserved * Use is subject to license terms. * - * Copyright (c) 2012, 2013, Intel Corporation. + * Copyright (c) 2012, 2014, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -41,7 +41,23 @@ #include "lod_internal.h" #include -#ifdef LPROCFS +/* + * Notice, all the functions below (except for lod_procfs_init() and + * lod_procfs_fini()) are not supposed to be used directly. They are + * called by Linux kernel's procfs. + */ + +#ifdef CONFIG_PROC_FS + +/** + * Show default stripe size. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_stripesize_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -53,6 +69,19 @@ static int lod_stripesize_seq_show(struct seq_file *m, void *v) lod->lod_desc.ld_default_stripe_size); } +/** + * Set default stripe size. + * + * \param[in] file proc file + * \param[in] buffer string containing the maximum number of bytes stored in + * each object before moving to the next object in the + * layout (if any) + * \param[in] count @buffer length + * \param[in] off unused for single entry + * + * \retval @count on success + * \retval negative error code if failed + */ static ssize_t lod_stripesize_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) @@ -75,6 +104,15 @@ lod_stripesize_seq_write(struct file *file, const char *buffer, } LPROC_SEQ_FOPS(lod_stripesize); +/** + * Show default stripe offset. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_stripeoffset_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -86,6 +124,20 @@ static int lod_stripeoffset_seq_show(struct seq_file *m, void *v) lod->lod_desc.ld_default_stripe_offset); } +/** + * Set default stripe offset. + * + * Usually contains -1 allowing Lustre to balance objects among OST + * otherwise may cause severe OST imbalance. + * + * \param[in] file proc file + * \param[in] buffer string describing starting OST index for new files + * \param[in] count @buffer length + * \param[in] off unused for single entry + * + * \retval @count on success + * \retval negative error code if failed + */ static ssize_t lod_stripeoffset_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) @@ -107,6 +159,15 @@ lod_stripeoffset_seq_write(struct file *file, const char *buffer, } LPROC_SEQ_FOPS(lod_stripeoffset); +/** + * Show default striping pattern (LOV_PATTERN_*). + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_stripetype_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -117,6 +178,18 @@ static int lod_stripetype_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%u\n", lod->lod_desc.ld_pattern); } +/** + * Set default striping pattern (a number, not a human-readable string). + * + * \param[in] file proc file + * \param[in] buffer string containing the default striping pattern for new + * files. This is an integer LOV_PATTERN_* value + * \param[in] count @buffer length + * \param[in] off unused for single entry + * + * \retval @count on success + * \retval negative error code if failed + */ static ssize_t lod_stripetype_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) @@ -138,6 +211,15 @@ lod_stripetype_seq_write(struct file *file, const char *buffer, } LPROC_SEQ_FOPS(lod_stripetype); +/** + * Show default number of stripes. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success, + * \retval negative error code if failed + */ static int lod_stripecount_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -149,6 +231,18 @@ static int lod_stripecount_seq_show(struct seq_file *m, void *v) (__s16)(lod->lod_desc.ld_default_stripe_count + 1) - 1); } +/** + * Set default number of stripes. + * + * \param[in] file proc file + * \param[in] buffer string containing the default number of stripes + * for new files + * \param[in] count @buffer length + * \param[in] off unused for single entry + * + * \retval @count on success + * \retval negative error code otherwise + */ static ssize_t lod_stripecount_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) @@ -170,6 +264,15 @@ lod_stripecount_seq_write(struct file *file, const char *buffer, } LPROC_SEQ_FOPS(lod_stripecount); +/** + * Show number of targets. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_numobd_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -181,6 +284,15 @@ static int lod_numobd_seq_show(struct seq_file *m, void *v) } LPROC_SEQ_FOPS_RO(lod_numobd); +/** + * Show number of active targets. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_activeobd_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -192,6 +304,15 @@ static int lod_activeobd_seq_show(struct seq_file *m, void *v) } LPROC_SEQ_FOPS_RO(lod_activeobd); +/** + * Show UUID of LOD device. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_desc_uuid_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -203,7 +324,20 @@ static int lod_desc_uuid_seq_show(struct seq_file *m, void *v) } LPROC_SEQ_FOPS_RO(lod_desc_uuid); -/* free priority (0-255): how badly user wants to choose empty osts */ +/** + * Show QoS priority parameter. + * + * The printed value is a percentage value (0-100%) indicating the priority + * of free space compared to performance. 0% means select OSTs equally + * regardless of their free space, 100% means select OSTs only by their free + * space even if it results in very imbalanced load on the OSTs. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_qos_priofree_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -214,8 +348,24 @@ static int lod_qos_priofree_seq_show(struct seq_file *m, void *v) (lod->lod_qos.lq_prio_free * 100 + 255) >> 8); } +/** + * Set QoS free space priority parameter. + * + * Set the relative priority of free OST space compared to OST load when OSTs + * are space imbalanced. See lod_qos_priofree_seq_show() for description of + * this parameter. See lod_qos_thresholdrr_seq_write() and lq_threshold_rr to + * determine what constitutes "space imbalanced" OSTs. + * + * \param[in] file proc file + * \param[in] buffer string which contains the free space priority (0-100) + * \param[in] count @buffer length + * \param[in] off unused for single entry + * + * \retval @count on success + * \retval negative error code if failed + */ static ssize_t -lod_qos_priofree_seq_write(struct file *file, const char *buffer, +lod_qos_priofree_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct seq_file *m = file->private_data; @@ -239,6 +389,15 @@ lod_qos_priofree_seq_write(struct file *file, const char *buffer, } LPROC_SEQ_FOPS(lod_qos_priofree); +/** + * Show threshold for "same space on all OSTs" rule. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_qos_thresholdrr_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -250,6 +409,23 @@ static int lod_qos_thresholdrr_seq_show(struct seq_file *m, void *v) (lod->lod_qos.lq_threshold_rr * 100 + 255) >> 8); } +/** + * Set threshold for "same space on all OSTs" rule. + * + * This sets the maximum percentage difference of free space between the most + * full and most empty OST in the currently available OSTs. If this percentage + * is exceeded, use the QoS allocator to select OSTs based on their available + * space so that more full OSTs are chosen less often, otherwise use the + * round-robin allocator for efficiency and performance. + + * \param[in] file proc file + * \param[in] buffer string containing percentage difference of free space + * \param[in] count @buffer length + * \param[in] off unused for single entry + * + * \retval @count on success + * \retval negative error code if failed + */ static ssize_t lod_qos_thresholdrr_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) @@ -275,6 +451,16 @@ lod_qos_thresholdrr_seq_write(struct file *file, const char *buffer, } LPROC_SEQ_FOPS(lod_qos_thresholdrr); +/** + * Show expiration period used to refresh cached statfs data, which + * is used to implement QoS/RR striping allocation algorithm. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_qos_maxage_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -285,6 +471,17 @@ static int lod_qos_maxage_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%u Sec\n", lod->lod_desc.ld_qos_maxage); } +/** + * Set expiration period used to refresh cached statfs data. + * + * \param[in] file proc file + * \param[in] buffer string contains maximum age of statfs data in seconds + * \param[in] count @buffer length + * \param[in] off unused for single entry + * + * \retval @count on success + * \retval negative error code if failed + */ static ssize_t lod_qos_maxage_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) @@ -317,6 +514,9 @@ lod_qos_maxage_seq_write(struct file *file, const char *buffer, sprintf(str, "%smaxage=%d", PARAM_OSP, val); lustre_cfg_bufs_set_string(&bufs, 1, str); lcfg = lustre_cfg_new(LCFG_PARAM, &bufs); + if (lcfg == NULL) + return -ENOMEM; + lod_getref(&lod->lod_ost_descs); lod_foreach_ost(lod, i) { next = &OST_TGT(lod,i)->ltd_ost->dd_lu_dev; @@ -377,6 +577,15 @@ static void *lod_osts_seq_next(struct seq_file *p, void *v, loff_t *pos) return NULL; } +/** + * Show active/inactive status for OST found by lod_osts_seq_next(). + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_osts_seq_show(struct seq_file *p, void *v) { struct obd_device *obd = p->private; @@ -438,6 +647,15 @@ LPROC_SEQ_FOPS_RO_TYPE(lod, dt_kbytesavail); LPROC_SEQ_FOPS_RO_TYPE(lod, dt_filestotal); LPROC_SEQ_FOPS_RO_TYPE(lod, dt_filesfree); +/** + * Show whether special failout mode for testing is enabled or not. + * + * \param[in] m seq file + * \param[in] v unused for single entry + * + * \retval 0 on success + * \retval negative error code if failed + */ static int lod_lmv_failout_seq_show(struct seq_file *m, void *v) { struct obd_device *dev = m->private; @@ -449,6 +667,21 @@ static int lod_lmv_failout_seq_show(struct seq_file *m, void *v) return seq_printf(m, "%d\n", lod->lod_lmv_failout ? 1 : 0); } +/** + * Enable/disable a special failout mode for testing. + * + * This determines whether the LMV will try to continue processing a striped + * directory even if it has a (partly) corrupted entry in the master directory, + * or if it will abort upon finding a corrupted slave directory entry. + * + * \param[in] file proc file + * \param[in] buffer string: 0 or non-zero to disable or enable LMV failout + * \param[in] count @buffer length + * \param[in] off unused for single entry + * + * \retval @count on success + * \retval negative error code if failed + */ static ssize_t lod_lmv_failout_seq_write(struct file *file, const char *buffer, size_t count, loff_t *off) @@ -475,7 +708,7 @@ lod_lmv_failout_seq_write(struct file *file, const char *buffer, } LPROC_SEQ_FOPS(lod_lmv_failout); -static struct lprocfs_seq_vars lprocfs_lod_obd_vars[] = { +static struct lprocfs_vars lprocfs_lod_obd_vars[] = { { .name = "uuid", .fops = &lod_uuid_fops }, { .name = "stripesize", @@ -500,17 +733,17 @@ static struct lprocfs_seq_vars lprocfs_lod_obd_vars[] = { .fops = &lod_qos_maxage_fops }, { .name = "lmv_failout", .fops = &lod_lmv_failout_fops }, - { 0 } + { NULL } }; -static struct lprocfs_seq_vars lprocfs_lod_osd_vars[] = { +static struct lprocfs_vars lprocfs_lod_osd_vars[] = { { "blocksize", &lod_dt_blksize_fops }, { "kbytestotal", &lod_dt_kbytestotal_fops }, { "kbytesfree", &lod_dt_kbytesfree_fops }, { "kbytesavail", &lod_dt_kbytesavail_fops }, { "filestotal", &lod_dt_filestotal_fops }, { "filesfree", &lod_dt_filesfree_fops }, - { 0 } + { NULL } }; static const struct file_operations lod_proc_target_fops = { @@ -521,6 +754,14 @@ static const struct file_operations lod_proc_target_fops = { .release = lprocfs_seq_release, }; +/** + * Initialize procfs entries for LOD. + * + * \param[in] lod LOD device + * + * \retval 0 on success + * \retval negative error code if failed + */ int lod_procfs_init(struct lod_device *lod) { struct obd_device *obd = lod2obd(lod); @@ -529,15 +770,15 @@ int lod_procfs_init(struct lod_device *lod) int rc; obd->obd_vars = lprocfs_lod_obd_vars; - rc = lprocfs_seq_obd_setup(obd); + rc = lprocfs_obd_setup(obd); if (rc) { CERROR("%s: cannot setup procfs entry: %d\n", obd->obd_name, rc); RETURN(rc); } - rc = lprocfs_seq_add_vars(obd->obd_proc_entry, lprocfs_lod_osd_vars, - &lod->lod_dt_dev); + rc = lprocfs_add_vars(obd->obd_proc_entry, lprocfs_lod_osd_vars, + &lod->lod_dt_dev); if (rc) { CERROR("%s: cannot setup procfs entry: %d\n", obd->obd_name, rc); @@ -552,9 +793,9 @@ int lod_procfs_init(struct lod_device *lod) GOTO(out, rc); } - lod->lod_pool_proc_entry = lprocfs_seq_register("pools", - obd->obd_proc_entry, - NULL, NULL); + lod->lod_pool_proc_entry = lprocfs_register("pools", + obd->obd_proc_entry, + NULL, NULL); if (IS_ERR(lod->lod_pool_proc_entry)) { rc = PTR_ERR(lod->lod_pool_proc_entry); lod->lod_pool_proc_entry = NULL; @@ -579,8 +820,8 @@ int lod_procfs_init(struct lod_device *lod) lod->lod_symlink = lprocfs_add_symlink(obd->obd_name, lov_proc_dir, "../lod/%s", obd->obd_name); if (lod->lod_symlink == NULL) - CERROR("could not register LOV symlink for " - "/proc/fs/lustre/lod/%s.", obd->obd_name); + CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n", + obd->obd_name); RETURN(0); out: @@ -589,6 +830,11 @@ out: return rc; } +/** + * Cleanup procfs entries registred for LOD. + * + * \param[in] lod LOD device + */ void lod_procfs_fini(struct lod_device *lod) { struct obd_device *obd = lod2obd(lod); @@ -604,5 +850,5 @@ void lod_procfs_fini(struct lod_device *lod) lprocfs_obd_cleanup(obd); } -#endif /* LPROCFS */ +#endif /* CONFIG_PROC_FS */