4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License version 2 for more details (a copy is included
14 * in the LICENSE file that accompanied this code).
16 * You should have received a copy of the GNU General Public License
17 * version 2 along with this program; If not, see
18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21 * CA 95054 USA or visit www.sun.com if you need additional information or
27 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
28 * Use is subject to license terms.
30 * Copyright (c) 2012, 2014, Intel Corporation.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
36 #define DEBUG_SUBSYSTEM S_CLASS
38 #include <lprocfs_status.h>
39 #include <obd_class.h>
40 #include <linux/seq_file.h>
41 #include "lod_internal.h"
42 #include <lustre_param.h>
45 * Notice, all the functions below (except for lod_procfs_init() and
46 * lod_procfs_fini()) are not supposed to be used directly. They are
47 * called by Linux kernel's procfs.
53 * Show default stripe size.
55 * \param[in] m seq file
56 * \param[in] v unused for single entry
58 * \retval 0 on success
59 * \retval negative error code if failed
61 static int lod_stripesize_seq_show(struct seq_file *m, void *v)
63 struct obd_device *dev = m->private;
64 struct lod_device *lod;
67 lod = lu2lod_dev(dev->obd_lu_dev);
68 return seq_printf(m, LPU64"\n",
69 lod->lod_desc.ld_default_stripe_size);
73 * Set default stripe size.
75 * \param[in] file proc file
76 * \param[in] buffer string containing the maximum number of bytes stored in
77 * each object before moving to the next object in the
79 * \param[in] count @buffer length
80 * \param[in] off unused for single entry
82 * \retval @count on success
83 * \retval negative error code if failed
86 lod_stripesize_seq_write(struct file *file, const char *buffer,
87 size_t count, loff_t *off)
89 struct seq_file *m = file->private_data;
90 struct obd_device *dev = m->private;
91 struct lod_device *lod;
96 lod = lu2lod_dev(dev->obd_lu_dev);
97 rc = lprocfs_write_u64_helper(buffer, count, &val);
101 lod_fix_desc_stripe_size(&val);
102 lod->lod_desc.ld_default_stripe_size = val;
105 LPROC_SEQ_FOPS(lod_stripesize);
108 * Show default stripe offset.
110 * \param[in] m seq file
111 * \param[in] v unused for single entry
113 * \retval 0 on success
114 * \retval negative error code if failed
116 static int lod_stripeoffset_seq_show(struct seq_file *m, void *v)
118 struct obd_device *dev = m->private;
119 struct lod_device *lod;
121 LASSERT(dev != NULL);
122 lod = lu2lod_dev(dev->obd_lu_dev);
123 return seq_printf(m, LPU64"\n",
124 lod->lod_desc.ld_default_stripe_offset);
128 * Set default stripe offset.
130 * Usually contains -1 allowing Lustre to balance objects among OST
131 * otherwise may cause severe OST imbalance.
133 * \param[in] file proc file
134 * \param[in] buffer string describing starting OST index for new files
135 * \param[in] count @buffer length
136 * \param[in] off unused for single entry
138 * \retval @count on success
139 * \retval negative error code if failed
142 lod_stripeoffset_seq_write(struct file *file, const char *buffer,
143 size_t count, loff_t *off)
145 struct seq_file *m = file->private_data;
146 struct obd_device *dev = m->private;
147 struct lod_device *lod;
151 LASSERT(dev != NULL);
152 lod = lu2lod_dev(dev->obd_lu_dev);
153 rc = lprocfs_write_u64_helper(buffer, count, &val);
157 lod->lod_desc.ld_default_stripe_offset = val;
160 LPROC_SEQ_FOPS(lod_stripeoffset);
163 * Show default striping pattern (LOV_PATTERN_*).
165 * \param[in] m seq file
166 * \param[in] v unused for single entry
168 * \retval 0 on success
169 * \retval negative error code if failed
171 static int lod_stripetype_seq_show(struct seq_file *m, void *v)
173 struct obd_device *dev = m->private;
174 struct lod_device *lod;
176 LASSERT(dev != NULL);
177 lod = lu2lod_dev(dev->obd_lu_dev);
178 return seq_printf(m, "%u\n", lod->lod_desc.ld_pattern);
182 * Set default striping pattern (a number, not a human-readable string).
184 * \param[in] file proc file
185 * \param[in] buffer string containing the default striping pattern for new
186 * files. This is an integer LOV_PATTERN_* value
187 * \param[in] count @buffer length
188 * \param[in] off unused for single entry
190 * \retval @count on success
191 * \retval negative error code if failed
194 lod_stripetype_seq_write(struct file *file, const char *buffer,
195 size_t count, loff_t *off)
197 struct seq_file *m = file->private_data;
198 struct obd_device *dev = m->private;
199 struct lod_device *lod;
202 LASSERT(dev != NULL);
203 lod = lu2lod_dev(dev->obd_lu_dev);
204 rc = lprocfs_write_helper(buffer, count, &val);
208 lod_fix_desc_pattern(&val);
209 lod->lod_desc.ld_pattern = val;
212 LPROC_SEQ_FOPS(lod_stripetype);
215 * Show default number of stripes.
217 * \param[in] m seq file
218 * \param[in] v unused for single entry
220 * \retval 0 on success,
221 * \retval negative error code if failed
223 static int lod_stripecount_seq_show(struct seq_file *m, void *v)
225 struct obd_device *dev = m->private;
226 struct lod_device *lod;
228 LASSERT(dev != NULL);
229 lod = lu2lod_dev(dev->obd_lu_dev);
230 return seq_printf(m, "%d\n",
231 (__s16)(lod->lod_desc.ld_default_stripe_count + 1) - 1);
235 * Set default number of stripes.
237 * \param[in] file proc file
238 * \param[in] buffer string containing the default number of stripes
240 * \param[in] count @buffer length
241 * \param[in] off unused for single entry
243 * \retval @count on success
244 * \retval negative error code otherwise
247 lod_stripecount_seq_write(struct file *file, const char *buffer,
248 size_t count, loff_t *off)
250 struct seq_file *m = file->private_data;
251 struct obd_device *dev = m->private;
252 struct lod_device *lod;
255 LASSERT(dev != NULL);
256 lod = lu2lod_dev(dev->obd_lu_dev);
257 rc = lprocfs_write_helper(buffer, count, &val);
261 lod_fix_desc_stripe_count(&val);
262 lod->lod_desc.ld_default_stripe_count = val;
265 LPROC_SEQ_FOPS(lod_stripecount);
268 * Show number of targets.
270 * \param[in] m seq file
271 * \param[in] v unused for single entry
273 * \retval 0 on success
274 * \retval negative error code if failed
276 static int lod_numobd_seq_show(struct seq_file *m, void *v)
278 struct obd_device *dev = m->private;
279 struct lod_device *lod;
281 LASSERT(dev != NULL);
282 lod = lu2lod_dev(dev->obd_lu_dev);
283 return seq_printf(m, "%u\n", lod->lod_desc.ld_tgt_count);
285 LPROC_SEQ_FOPS_RO(lod_numobd);
288 * Show number of active targets.
290 * \param[in] m seq file
291 * \param[in] v unused for single entry
293 * \retval 0 on success
294 * \retval negative error code if failed
296 static int lod_activeobd_seq_show(struct seq_file *m, void *v)
298 struct obd_device *dev = m->private;
299 struct lod_device *lod;
301 LASSERT(dev != NULL);
302 lod = lu2lod_dev(dev->obd_lu_dev);
303 return seq_printf(m, "%u\n", lod->lod_desc.ld_active_tgt_count);
305 LPROC_SEQ_FOPS_RO(lod_activeobd);
308 * Show UUID of LOD device.
310 * \param[in] m seq file
311 * \param[in] v unused for single entry
313 * \retval 0 on success
314 * \retval negative error code if failed
316 static int lod_desc_uuid_seq_show(struct seq_file *m, void *v)
318 struct obd_device *dev = m->private;
319 struct lod_device *lod;
321 LASSERT(dev != NULL);
322 lod = lu2lod_dev(dev->obd_lu_dev);
323 return seq_printf(m, "%s\n", lod->lod_desc.ld_uuid.uuid);
325 LPROC_SEQ_FOPS_RO(lod_desc_uuid);
328 * Show QoS priority parameter.
330 * The printed value is a percentage value (0-100%) indicating the priority
331 * of free space compared to performance. 0% means select OSTs equally
332 * regardless of their free space, 100% means select OSTs only by their free
333 * space even if it results in very imbalanced load on the OSTs.
335 * \param[in] m seq file
336 * \param[in] v unused for single entry
338 * \retval 0 on success
339 * \retval negative error code if failed
341 static int lod_qos_priofree_seq_show(struct seq_file *m, void *v)
343 struct obd_device *dev = m->private;
344 struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
346 LASSERT(lod != NULL);
347 return seq_printf(m, "%d%%\n",
348 (lod->lod_qos.lq_prio_free * 100 + 255) >> 8);
352 * Set QoS free space priority parameter.
354 * Set the relative priority of free OST space compared to OST load when OSTs
355 * are space imbalanced. See lod_qos_priofree_seq_show() for description of
356 * this parameter. See lod_qos_thresholdrr_seq_write() and lq_threshold_rr to
357 * determine what constitutes "space imbalanced" OSTs.
359 * \param[in] file proc file
360 * \param[in] buffer string which contains the free space priority (0-100)
361 * \param[in] count @buffer length
362 * \param[in] off unused for single entry
364 * \retval @count on success
365 * \retval negative error code if failed
368 lod_qos_priofree_seq_write(struct file *file, const char __user *buffer,
369 size_t count, loff_t *off)
371 struct seq_file *m = file->private_data;
372 struct obd_device *dev = m->private;
373 struct lod_device *lod;
376 LASSERT(dev != NULL);
377 lod = lu2lod_dev(dev->obd_lu_dev);
379 rc = lprocfs_write_helper(buffer, count, &val);
385 lod->lod_qos.lq_prio_free = (val << 8) / 100;
386 lod->lod_qos.lq_dirty = 1;
387 lod->lod_qos.lq_reset = 1;
390 LPROC_SEQ_FOPS(lod_qos_priofree);
393 * Show threshold for "same space on all OSTs" rule.
395 * \param[in] m seq file
396 * \param[in] v unused for single entry
398 * \retval 0 on success
399 * \retval negative error code if failed
401 static int lod_qos_thresholdrr_seq_show(struct seq_file *m, void *v)
403 struct obd_device *dev = m->private;
404 struct lod_device *lod;
406 LASSERT(dev != NULL);
407 lod = lu2lod_dev(dev->obd_lu_dev);
408 return seq_printf(m, "%d%%\n",
409 (lod->lod_qos.lq_threshold_rr * 100 + 255) >> 8);
413 * Set threshold for "same space on all OSTs" rule.
415 * This sets the maximum percentage difference of free space between the most
416 * full and most empty OST in the currently available OSTs. If this percentage
417 * is exceeded, use the QoS allocator to select OSTs based on their available
418 * space so that more full OSTs are chosen less often, otherwise use the
419 * round-robin allocator for efficiency and performance.
421 * \param[in] file proc file
422 * \param[in] buffer string containing percentage difference of free space
423 * \param[in] count @buffer length
424 * \param[in] off unused for single entry
426 * \retval @count on success
427 * \retval negative error code if failed
430 lod_qos_thresholdrr_seq_write(struct file *file, const char *buffer,
431 size_t count, loff_t *off)
433 struct seq_file *m = file->private_data;
434 struct obd_device *dev = m->private;
435 struct lod_device *lod;
438 LASSERT(dev != NULL);
439 lod = lu2lod_dev(dev->obd_lu_dev);
441 rc = lprocfs_write_helper(buffer, count, &val);
445 if (val > 100 || val < 0)
448 lod->lod_qos.lq_threshold_rr = (val << 8) / 100;
449 lod->lod_qos.lq_dirty = 1;
452 LPROC_SEQ_FOPS(lod_qos_thresholdrr);
455 * Show expiration period used to refresh cached statfs data, which
456 * is used to implement QoS/RR striping allocation algorithm.
458 * \param[in] m seq file
459 * \param[in] v unused for single entry
461 * \retval 0 on success
462 * \retval negative error code if failed
464 static int lod_qos_maxage_seq_show(struct seq_file *m, void *v)
466 struct obd_device *dev = m->private;
467 struct lod_device *lod;
469 LASSERT(dev != NULL);
470 lod = lu2lod_dev(dev->obd_lu_dev);
471 return seq_printf(m, "%u Sec\n", lod->lod_desc.ld_qos_maxage);
475 * Set expiration period used to refresh cached statfs data.
477 * \param[in] file proc file
478 * \param[in] buffer string contains maximum age of statfs data in seconds
479 * \param[in] count @buffer length
480 * \param[in] off unused for single entry
482 * \retval @count on success
483 * \retval negative error code if failed
486 lod_qos_maxage_seq_write(struct file *file, const char *buffer,
487 size_t count, loff_t *off)
489 struct seq_file *m = file->private_data;
490 struct obd_device *dev = m->private;
491 struct lustre_cfg_bufs bufs;
492 struct lod_device *lod;
493 struct lu_device *next;
494 struct lustre_cfg *lcfg;
499 LASSERT(dev != NULL);
500 lod = lu2lod_dev(dev->obd_lu_dev);
502 rc = lprocfs_write_helper(buffer, count, &val);
508 lod->lod_desc.ld_qos_maxage = val;
511 * propogate the value down to OSPs
513 lustre_cfg_bufs_reset(&bufs, NULL);
514 sprintf(str, "%smaxage=%d", PARAM_OSP, val);
515 lustre_cfg_bufs_set_string(&bufs, 1, str);
516 lcfg = lustre_cfg_new(LCFG_PARAM, &bufs);
520 lod_getref(&lod->lod_ost_descs);
521 lod_foreach_ost(lod, i) {
522 next = &OST_TGT(lod,i)->ltd_ost->dd_lu_dev;
523 rc = next->ld_ops->ldo_process_config(NULL, next, lcfg);
525 CERROR("can't set maxage on #%d: %d\n", i, rc);
527 lod_putref(lod, &lod->lod_ost_descs);
528 lustre_cfg_free(lcfg);
532 LPROC_SEQ_FOPS(lod_qos_maxage);
534 static void *lod_osts_seq_start(struct seq_file *p, loff_t *pos)
536 struct obd_device *dev = p->private;
537 struct lod_device *lod;
539 LASSERT(dev != NULL);
540 lod = lu2lod_dev(dev->obd_lu_dev);
542 lod_getref(&lod->lod_ost_descs); /* released in lod_osts_seq_stop */
543 if (*pos >= lod->lod_ost_bitmap->size)
546 *pos = find_next_bit(lod->lod_ost_bitmap->data,
547 lod->lod_ost_bitmap->size, *pos);
548 if (*pos < lod->lod_ost_bitmap->size)
549 return OST_TGT(lod,*pos);
554 static void lod_osts_seq_stop(struct seq_file *p, void *v)
556 struct obd_device *dev = p->private;
557 struct lod_device *lod;
559 LASSERT(dev != NULL);
560 lod = lu2lod_dev(dev->obd_lu_dev);
561 lod_putref(lod, &lod->lod_ost_descs);
564 static void *lod_osts_seq_next(struct seq_file *p, void *v, loff_t *pos)
566 struct obd_device *dev = p->private;
567 struct lod_device *lod = lu2lod_dev(dev->obd_lu_dev);
569 if (*pos >= lod->lod_ost_bitmap->size - 1)
572 *pos = find_next_bit(lod->lod_ost_bitmap->data,
573 lod->lod_ost_bitmap->size, *pos + 1);
574 if (*pos < lod->lod_ost_bitmap->size)
575 return OST_TGT(lod,*pos);
581 * Show active/inactive status for OST found by lod_osts_seq_next().
583 * \param[in] m seq file
584 * \param[in] v unused for single entry
586 * \retval 0 on success
587 * \retval negative error code if failed
589 static int lod_osts_seq_show(struct seq_file *p, void *v)
591 struct obd_device *obd = p->private;
592 struct lod_ost_desc *ost_desc = v;
593 struct lod_device *lod;
595 struct dt_device *next;
596 struct obd_statfs sfs;
598 LASSERT(obd->obd_lu_dev);
599 lod = lu2lod_dev(obd->obd_lu_dev);
601 idx = ost_desc->ltd_index;
602 next = OST_TGT(lod,idx)->ltd_ost;
606 /* XXX: should be non-NULL env, but it's very expensive */
608 rc = dt_statfs(NULL, next, &sfs);
609 if (rc == -ENOTCONN) {
615 return seq_printf(p, "%d: %s %sACTIVE\n", idx,
616 obd_uuid2str(&ost_desc->ltd_uuid),
620 static const struct seq_operations lod_osts_sops = {
621 .start = lod_osts_seq_start,
622 .stop = lod_osts_seq_stop,
623 .next = lod_osts_seq_next,
624 .show = lod_osts_seq_show,
627 static int lod_osts_seq_open(struct inode *inode, struct file *file)
629 struct seq_file *seq;
632 rc = seq_open(file, &lod_osts_sops);
636 seq = file->private_data;
637 seq->private = PDE_DATA(inode);
641 LPROC_SEQ_FOPS_RO_TYPE(lod, uuid);
643 LPROC_SEQ_FOPS_RO_TYPE(lod, dt_blksize);
644 LPROC_SEQ_FOPS_RO_TYPE(lod, dt_kbytestotal);
645 LPROC_SEQ_FOPS_RO_TYPE(lod, dt_kbytesfree);
646 LPROC_SEQ_FOPS_RO_TYPE(lod, dt_kbytesavail);
647 LPROC_SEQ_FOPS_RO_TYPE(lod, dt_filestotal);
648 LPROC_SEQ_FOPS_RO_TYPE(lod, dt_filesfree);
651 * Show whether special failout mode for testing is enabled or not.
653 * \param[in] m seq file
654 * \param[in] v unused for single entry
656 * \retval 0 on success
657 * \retval negative error code if failed
659 static int lod_lmv_failout_seq_show(struct seq_file *m, void *v)
661 struct obd_device *dev = m->private;
662 struct lod_device *lod;
664 LASSERT(dev != NULL);
665 lod = lu2lod_dev(dev->obd_lu_dev);
667 return seq_printf(m, "%d\n", lod->lod_lmv_failout ? 1 : 0);
671 * Enable/disable a special failout mode for testing.
673 * This determines whether the LMV will try to continue processing a striped
674 * directory even if it has a (partly) corrupted entry in the master directory,
675 * or if it will abort upon finding a corrupted slave directory entry.
677 * \param[in] file proc file
678 * \param[in] buffer string: 0 or non-zero to disable or enable LMV failout
679 * \param[in] count @buffer length
680 * \param[in] off unused for single entry
682 * \retval @count on success
683 * \retval negative error code if failed
686 lod_lmv_failout_seq_write(struct file *file, const char *buffer,
687 size_t count, loff_t *off)
689 struct seq_file *m = file->private_data;
690 struct obd_device *dev = m->private;
691 struct lod_device *lod;
695 LASSERT(dev != NULL);
696 lod = lu2lod_dev(dev->obd_lu_dev);
698 rc = lprocfs_write_helper(buffer, count, &val);
703 lod->lod_lmv_failout = 1;
705 lod->lod_lmv_failout = 0;
709 LPROC_SEQ_FOPS(lod_lmv_failout);
711 static struct lprocfs_seq_vars lprocfs_lod_obd_vars[] = {
713 .fops = &lod_uuid_fops },
714 { .name = "stripesize",
715 .fops = &lod_stripesize_fops },
716 { .name = "stripeoffset",
717 .fops = &lod_stripeoffset_fops },
718 { .name = "stripecount",
719 .fops = &lod_stripecount_fops },
720 { .name = "stripetype",
721 .fops = &lod_stripetype_fops },
723 .fops = &lod_numobd_fops },
724 { .name = "activeobd",
725 .fops = &lod_activeobd_fops },
726 { .name = "desc_uuid",
727 .fops = &lod_desc_uuid_fops },
728 { .name = "qos_prio_free",
729 .fops = &lod_qos_priofree_fops },
730 { .name = "qos_threshold_rr",
731 .fops = &lod_qos_thresholdrr_fops },
732 { .name = "qos_maxage",
733 .fops = &lod_qos_maxage_fops },
734 { .name = "lmv_failout",
735 .fops = &lod_lmv_failout_fops },
739 static struct lprocfs_seq_vars lprocfs_lod_osd_vars[] = {
740 { "blocksize", &lod_dt_blksize_fops },
741 { "kbytestotal", &lod_dt_kbytestotal_fops },
742 { "kbytesfree", &lod_dt_kbytesfree_fops },
743 { "kbytesavail", &lod_dt_kbytesavail_fops },
744 { "filestotal", &lod_dt_filestotal_fops },
745 { "filesfree", &lod_dt_filesfree_fops },
749 static const struct file_operations lod_proc_target_fops = {
750 .owner = THIS_MODULE,
751 .open = lod_osts_seq_open,
754 .release = lprocfs_seq_release,
758 * Initialize procfs entries for LOD.
760 * \param[in] lod LOD device
762 * \retval 0 on success
763 * \retval negative error code if failed
765 int lod_procfs_init(struct lod_device *lod)
767 struct obd_device *obd = lod2obd(lod);
768 struct proc_dir_entry *lov_proc_dir = NULL;
769 struct obd_type *type;
772 obd->obd_vars = lprocfs_lod_obd_vars;
773 rc = lprocfs_obd_setup(obd);
775 CERROR("%s: cannot setup procfs entry: %d\n",
780 rc = lprocfs_seq_add_vars(obd->obd_proc_entry, lprocfs_lod_osd_vars,
783 CERROR("%s: cannot setup procfs entry: %d\n",
788 rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
789 0444, &lod_proc_target_fops, obd);
791 CWARN("%s: Error adding the target_obd file %d\n",
796 lod->lod_pool_proc_entry = lprocfs_seq_register("pools",
799 if (IS_ERR(lod->lod_pool_proc_entry)) {
800 rc = PTR_ERR(lod->lod_pool_proc_entry);
801 lod->lod_pool_proc_entry = NULL;
802 CWARN("%s: Failed to create pool proc file: %d\n",
807 /* If the real LOV is present which is the case for setups
808 * with both server and clients on the same node then use
809 * the LOV's proc root */
810 type = class_search_type(LUSTRE_LOV_NAME);
811 if (type != NULL && type->typ_procroot != NULL)
812 lov_proc_dir = type->typ_procroot;
814 lov_proc_dir = obd->obd_type->typ_procsym;
816 if (lov_proc_dir == NULL)
819 /* for compatibility we link old procfs's LOV entries to lod ones */
820 lod->lod_symlink = lprocfs_add_symlink(obd->obd_name, lov_proc_dir,
821 "../lod/%s", obd->obd_name);
822 if (lod->lod_symlink == NULL)
823 CERROR("cannot create LOV symlink for /proc/fs/lustre/lod/%s\n",
828 lprocfs_obd_cleanup(obd);
834 * Cleanup procfs entries registred for LOD.
836 * \param[in] lod LOD device
838 void lod_procfs_fini(struct lod_device *lod)
840 struct obd_device *obd = lod2obd(lod);
842 if (lod->lod_symlink != NULL)
843 lprocfs_remove(&lod->lod_symlink);
845 if (lod->lod_pool_proc_entry != NULL) {
846 lprocfs_remove(&lod->lod_pool_proc_entry);
847 lod->lod_pool_proc_entry = NULL;
850 lprocfs_obd_cleanup(obd);