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.gnu.org/licenses/gpl-2.0.html
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Use is subject to license terms.
26 * Copyright (c) 2012, 2013, 2014 Intel Corporation.
29 * This file is part of Lustre, http://www.lustre.org/
30 * Lustre is a trademark of Sun Microsystems, Inc.
32 * lustre/osp/lproc_osp.c
34 * Lustre OST Proxy Device (OSP), procfs functions
36 * Author: Alex Zhuravlev <alexey.zhuravlev@intel.com>
39 #define DEBUG_SUBSYSTEM S_CLASS
41 #include "osp_internal.h"
45 * Show OSP active status
47 * \param[in] m seq_file handle
48 * \param[in] data unused for single entry
49 * \retval 0 on success
50 * \retval negative number on error
52 static int osp_active_seq_show(struct seq_file *m, void *data)
54 struct obd_device *dev = m->private;
57 LPROCFS_CLIMP_CHECK(dev);
58 rc = seq_printf(m, "%d\n", !dev->u.cli.cl_import->imp_deactive);
59 LPROCFS_CLIMP_EXIT(dev);
64 * Activate/Deactivate OSP
66 * \param[in] file proc file
67 * \param[in] buffer string, which is "1" or "0" to activate/deactivate OSP
68 * \param[in] count \a buffer length
69 * \param[in] off unused for single entry
70 * \retval \a count on success
71 * \retval negative number on error
74 osp_active_seq_write(struct file *file, const char *buffer,
75 size_t count, loff_t *off)
77 struct seq_file *m = file->private_data;
78 struct obd_device *dev = m->private;
81 rc = lprocfs_write_helper(buffer, count, &val);
84 if (val < 0 || val > 1)
87 LPROCFS_CLIMP_CHECK(dev);
89 if (dev->u.cli.cl_import->imp_deactive == val)
90 rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
92 CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n",
95 LPROCFS_CLIMP_EXIT(dev);
98 LPROC_SEQ_FOPS(osp_active);
101 * Show number of RPCs in flight
103 * \param[in] m seq_file handle
104 * \param[in] data unused for single entry
105 * \retval 0 on success
106 * \retval negative number on error
108 static int osp_syn_in_flight_seq_show(struct seq_file *m, void *data)
110 struct obd_device *dev = m->private;
111 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
116 return seq_printf(m, "%u\n", osp->opd_syn_rpc_in_flight);
118 LPROC_SEQ_FOPS_RO(osp_syn_in_flight);
121 * Show number of RPCs in processing (including uncommitted by OST)
123 * \param[in] m seq_file handle
124 * \param[in] data unused for single entry
125 * \retval 0 on success
126 * \retval negative number on error
128 static int osp_syn_in_prog_seq_show(struct seq_file *m, void *data)
130 struct obd_device *dev = m->private;
131 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
136 return seq_printf(m, "%u\n", osp->opd_syn_rpc_in_progress);
138 LPROC_SEQ_FOPS_RO(osp_syn_in_prog);
141 * Show number of changes to sync
143 * \param[in] m seq_file handle
144 * \param[in] data unused for single entry
145 * \retval 0 on success
146 * \retval negative number on error
148 static int osp_syn_changes_seq_show(struct seq_file *m, void *data)
150 struct obd_device *dev = m->private;
151 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
156 return seq_printf(m, "%lu\n", osp->opd_syn_changes);
162 * \param[in] file proc file
163 * \param[in] buffer unused because any input will do
164 * \param[in] count \a buffer length
165 * \param[in] off unused for single entry
166 * \retval \a count on success
167 * \retval negative number on error
169 static ssize_t osp_syn_changes_seq_write(struct file *file, const char *buffer,
170 size_t count, loff_t *off)
172 struct seq_file *m = file->private_data;
173 struct obd_device *dev = m->private;
174 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
178 rc = lu_env_init(&env, LCT_LOCAL);
182 rc = dt_sync(&env, &osp->opd_dt_dev);
185 return rc == 0 ? count : rc;
187 LPROC_SEQ_FOPS(osp_syn_changes);
190 * Show maximum number of RPCs in flight allowed
192 * \param[in] m seq_file handle
193 * \param[in] data unused for single entry
194 * \retval 0 on success
195 * \retval negative number on error
197 static int osp_max_rpcs_in_flight_seq_show(struct seq_file *m, void *data)
199 struct obd_device *dev = m->private;
200 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
205 return seq_printf(m, "%u\n", osp->opd_syn_max_rpc_in_flight);
209 * Change maximum number of RPCs in flight allowed
211 * \param[in] file proc file
212 * \param[in] buffer string which represents maximum number
213 * \param[in] count \a buffer length
214 * \param[in] off unused for single entry
215 * \retval \a count on success
216 * \retval negative number on error
219 osp_max_rpcs_in_flight_seq_write(struct file *file, const char *buffer,
220 size_t count, loff_t *off)
222 struct seq_file *m = file->private_data;
223 struct obd_device *dev = m->private;
224 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
230 rc = lprocfs_write_helper(buffer, count, &val);
237 osp->opd_syn_max_rpc_in_flight = val;
240 LPROC_SEQ_FOPS(osp_max_rpcs_in_flight);
243 * Show maximum number of RPCs in processing allowed
245 * \param[in] m seq_file handle
246 * \param[in] data unused
247 * \retval 0 on success
248 * \retval negative number on error
250 static int osp_max_rpcs_in_prog_seq_show(struct seq_file *m, void *data)
252 struct obd_device *dev = m->private;
253 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
258 return seq_printf(m, "%u\n", osp->opd_syn_max_rpc_in_progress);
262 * Change maximum number of RPCs in processing allowed
264 * \param[in] file proc file
265 * \param[in] buffer string which represents maximum number
266 * \param[in] count \a buffer length
267 * \param[in] off unused for single entry
268 * \retval \a count on success
269 * \retval negative number on error
272 osp_max_rpcs_in_prog_seq_write(struct file *file, const char *buffer,
273 size_t count, loff_t *off)
275 struct seq_file *m = file->private_data;
276 struct obd_device *dev = m->private;
277 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
283 rc = lprocfs_write_helper(buffer, count, &val);
290 osp->opd_syn_max_rpc_in_progress = val;
294 LPROC_SEQ_FOPS(osp_max_rpcs_in_prog);
297 * Show number of objects to precreate next time
299 * \param[in] m seq_file handle
300 * \param[in] data unused for single entry
301 * \retval 0 on success
302 * \retval negative number on error
304 static int osp_create_count_seq_show(struct seq_file *m, void *data)
306 struct obd_device *obd = m->private;
307 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
309 if (osp == NULL || osp->opd_pre == NULL)
312 return seq_printf(m, "%d\n", osp->opd_pre_grow_count);
316 * Change number of objects to precreate next time
318 * \param[in] file proc file
319 * \param[in] buffer string which represents number of objects to precreate
320 * \param[in] count \a buffer length
321 * \param[in] off unused for single entry
322 * \retval \a count on success
323 * \retval negative number on error
326 osp_create_count_seq_write(struct file *file, const char *buffer,
327 size_t count, loff_t *off)
329 struct seq_file *m = file->private_data;
330 struct obd_device *obd = m->private;
331 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
334 if (osp == NULL || osp->opd_pre == NULL)
337 rc = lprocfs_write_helper(buffer, count, &val);
341 /* The MDT ALWAYS needs to limit the precreate count to
342 * OST_MAX_PRECREATE, and the constant cannot be changed
343 * because it is a value shared between the OSP and OST
344 * that is the maximum possible number of objects that will
345 * ever be handled by MDT->OST recovery processing.
347 * If the OST ever gets a request to delete more orphans,
348 * this implies that something has gone badly on the MDT
349 * and the OST will refuse to delete so much data from the
350 * filesystem as a safety measure. */
351 if (val < OST_MIN_PRECREATE || val > OST_MAX_PRECREATE)
353 if (val > osp->opd_pre_max_grow_count)
356 for (i = 1; (i << 1) <= val; i <<= 1)
358 osp->opd_pre_grow_count = i;
362 LPROC_SEQ_FOPS(osp_create_count);
365 * Show maximum number of objects to precreate
367 * \param[in] m seq_file handle
368 * \param[in] data unused for single entry
369 * \retval 0 on success
370 * \retval negative number on error
372 static int osp_max_create_count_seq_show(struct seq_file *m, void *data)
374 struct obd_device *obd = m->private;
375 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
377 if (osp == NULL || osp->opd_pre == NULL)
380 return seq_printf(m, "%d\n", osp->opd_pre_max_grow_count);
384 * Change maximum number of objects to precreate
386 * \param[in] file proc file
387 * \param[in] buffer string which represents maximum number
388 * \param[in] count \a buffer length
389 * \param[in] off unused for single entry
390 * \retval \a count on success
391 * \retval negative number on error
394 osp_max_create_count_seq_write(struct file *file, const char *buffer,
395 size_t count, loff_t *off)
397 struct seq_file *m = file->private_data;
398 struct obd_device *obd = m->private;
399 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
402 if (osp == NULL || osp->opd_pre == NULL)
405 rc = lprocfs_write_helper(buffer, count, &val);
411 if (val > OST_MAX_PRECREATE)
414 if (osp->opd_pre_grow_count > val)
415 osp->opd_pre_grow_count = val;
417 osp->opd_pre_max_grow_count = val;
421 LPROC_SEQ_FOPS(osp_max_create_count);
424 * Show last id to assign in creation
426 * \param[in] m seq_file handle
427 * \param[in] data unused for single entry
428 * \retval 0 on success
429 * \retval negative number on error
431 static int osp_prealloc_next_id_seq_show(struct seq_file *m, void *data)
433 struct obd_device *obd = m->private;
434 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
436 if (osp == NULL || osp->opd_pre == NULL)
439 return seq_printf(m, "%u\n", fid_oid(&osp->opd_pre_used_fid) + 1);
441 LPROC_SEQ_FOPS_RO(osp_prealloc_next_id);
444 * Show last created id OST reported
446 * \param[in] m seq_file handle
447 * \param[in] data unused for single entry
448 * \retval 0 on success
449 * \retval negative number on error
451 static int osp_prealloc_last_id_seq_show(struct seq_file *m, void *data)
453 struct obd_device *obd = m->private;
454 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
456 if (osp == NULL || osp->opd_pre == NULL)
459 return seq_printf(m, "%u\n", fid_oid(&osp->opd_pre_last_created_fid));
461 LPROC_SEQ_FOPS_RO(osp_prealloc_last_id);
464 * Show next FID sequence to precreate
466 * \param[in] m seq_file handle
467 * \param[in] data unused for single entry
468 * \retval 0 on success
469 * \retval negative number on error
471 static int osp_prealloc_next_seq_seq_show(struct seq_file *m, void *data)
473 struct obd_device *obd = m->private;
474 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
476 if (osp == NULL || osp->opd_pre == NULL)
479 return seq_printf(m, LPX64"\n", fid_seq(&osp->opd_pre_used_fid));
481 LPROC_SEQ_FOPS_RO(osp_prealloc_next_seq);
484 * Show last created FID sequence OST reported
486 * \param[in] m seq_file handle
487 * \param[in] data unused for single entry
488 * \retval 0 on success
489 * \retval negative number on error
491 static int osp_prealloc_last_seq_seq_show(struct seq_file *m, void *data)
493 struct obd_device *obd = m->private;
494 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
496 if (osp == NULL || osp->opd_pre == NULL)
499 return seq_printf(m, LPX64"\n",
500 fid_seq(&osp->opd_pre_last_created_fid));
502 LPROC_SEQ_FOPS_RO(osp_prealloc_last_seq);
505 * Show the number of ids reserved by declare
507 * \param[in] m seq_file handle
508 * \param[in] data unused for single entry
509 * \retval 0 on success
510 * \retval negative number on error
512 static int osp_prealloc_reserved_seq_show(struct seq_file *m, void *data)
514 struct obd_device *obd = m->private;
515 struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
517 if (osp == NULL || osp->opd_pre == NULL)
520 return seq_printf(m, LPU64"\n", osp->opd_pre_reserved);
522 LPROC_SEQ_FOPS_RO(osp_prealloc_reserved);
525 * Show interval (in seconds) to update statfs data
527 * \param[in] m seq_file handle
528 * \param[in] data unused for single entry
529 * \retval 0 on success
530 * \retval negative number on error
532 static int osp_maxage_seq_show(struct seq_file *m, void *data)
534 struct obd_device *dev = m->private;
535 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
540 return seq_printf(m, "%u\n", osp->opd_statfs_maxage);
544 * Change interval to update statfs data
546 * \param[in] file proc file
547 * \param[in] buffer string which represents statfs interval (in seconds)
548 * \param[in] count \a buffer length
549 * \param[in] off unused for single entry
550 * \retval \a count on success
551 * \retval negative number on error
554 osp_maxage_seq_write(struct file *file, const char *buffer,
555 size_t count, loff_t *off)
557 struct seq_file *m = file->private_data;
558 struct obd_device *dev = m->private;
559 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
565 rc = lprocfs_write_helper(buffer, count, &val);
572 osp->opd_statfs_maxage = val;
576 LPROC_SEQ_FOPS(osp_maxage);
579 * Show current precreation status: output 0 means success, otherwise negative
582 * \param[in] m seq_file handle
583 * \param[in] data unused for single entry
584 * \retval 0 on success
585 * \retval negative number on error
587 static int osp_pre_status_seq_show(struct seq_file *m, void *data)
589 struct obd_device *dev = m->private;
590 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
592 if (osp == NULL || osp->opd_pre == NULL)
595 return seq_printf(m, "%d\n", osp->opd_pre_status);
597 LPROC_SEQ_FOPS_RO(osp_pre_status);
600 * Show the number of RPCs in processing (including uncommitted by OST) plus
601 * changes to sync, i.e. this is the total number of changes OST needs to apply
604 * This counter is used to determine if OST has space returned. A zero value
605 * indicates that OST storage space consumed by destroyed objects has been freed
606 * on disk, the associated llog records have been cleared, and no synchronous
607 * RPC are being processed.
609 * \param[in] m seq_file handle
610 * \param[in] data unused for single entry
611 * \retval 0 on success
612 * \retval negative number on error
614 static int osp_destroys_in_flight_seq_show(struct seq_file *m, void *data)
616 struct obd_device *dev = m->private;
617 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
622 return seq_printf(m, "%lu\n",
623 osp->opd_syn_rpc_in_progress + osp->opd_syn_changes);
625 LPROC_SEQ_FOPS_RO(osp_destroys_in_flight);
628 * Show changes synced from previous mount
630 * \param[in] m seq_file handle
631 * \param[in] data unused for single entry
632 * \retval 0 on success
633 * \retval negative number on error
635 static int osp_old_sync_processed_seq_show(struct seq_file *m, void *data)
637 struct obd_device *dev = m->private;
638 struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
643 return seq_printf(m, "%d\n", osp->opd_syn_prev_done);
645 LPROC_SEQ_FOPS_RO(osp_old_sync_processed);
648 * Show maximum number of RPCs in flight
650 * \param[in] m seq_file handle
651 * \param[in] data unused for single entry
652 * \retval 0 on success
653 * \retval negative number on error
656 osp_lfsck_max_rpcs_in_flight_seq_show(struct seq_file *m, void *data)
658 struct obd_device *dev = m->private;
661 max = obd_get_max_rpcs_in_flight(&dev->u.cli);
662 return seq_printf(m, "%u\n", max);
666 * Change maximum number of RPCs in flight
668 * \param[in] file proc file
669 * \param[in] buffer string which represents maximum number of RPCs in flight
670 * \param[in] count \a buffer length
671 * \param[in] off unused for single entry
672 * \retval \a count on success
673 * \retval negative number on error
676 osp_lfsck_max_rpcs_in_flight_seq_write(struct file *file,
677 const char __user *buffer,
678 size_t count, loff_t *off)
680 struct seq_file *m = file->private_data;
681 struct obd_device *dev = m->private;
685 rc = lprocfs_write_helper(buffer, count, &val);
687 rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
694 LPROC_SEQ_FOPS(osp_lfsck_max_rpcs_in_flight);
696 LPROC_SEQ_FOPS_WO_TYPE(osp, ping);
697 LPROC_SEQ_FOPS_RO_TYPE(osp, uuid);
698 LPROC_SEQ_FOPS_RO_TYPE(osp, connect_flags);
699 LPROC_SEQ_FOPS_RO_TYPE(osp, server_uuid);
700 LPROC_SEQ_FOPS_RO_TYPE(osp, conn_uuid);
703 * Show maximum pages per bulk RPC
705 * \param[in] m seq_file handle
706 * \param[in] data unused for single entry
707 * \retval 0 on success
708 * \retval negative number on error
710 static int osp_max_pages_per_rpc_seq_show(struct seq_file *m, void *v)
712 return lprocfs_obd_max_pages_per_rpc_seq_show(m, m->private);
714 LPROC_SEQ_FOPS_RO(osp_max_pages_per_rpc);
715 LPROC_SEQ_FOPS_RO_TYPE(osp, timeouts);
717 LPROC_SEQ_FOPS_RW_TYPE(osp, import);
718 LPROC_SEQ_FOPS_RO_TYPE(osp, state);
720 static struct lprocfs_seq_vars lprocfs_osp_obd_vars[] = {
722 .fops = &osp_uuid_fops },
724 .fops = &osp_ping_fops,
726 { .name = "connect_flags",
727 .fops = &osp_connect_flags_fops },
728 { .name = "ost_server_uuid",
729 .fops = &osp_server_uuid_fops },
730 { .name = "ost_conn_uuid",
731 .fops = &osp_conn_uuid_fops },
733 .fops = &osp_active_fops },
734 { .name = "max_rpcs_in_flight",
735 .fops = &osp_max_rpcs_in_flight_fops },
736 { .name = "max_rpcs_in_progress",
737 .fops = &osp_max_rpcs_in_prog_fops },
738 { .name = "create_count",
739 .fops = &osp_create_count_fops },
740 { .name = "max_create_count",
741 .fops = &osp_max_create_count_fops },
742 { .name = "prealloc_next_id",
743 .fops = &osp_prealloc_next_id_fops },
744 { .name = "prealloc_next_seq",
745 .fops = &osp_prealloc_next_seq_fops },
746 { .name = "prealloc_last_id",
747 .fops = &osp_prealloc_last_id_fops },
748 { .name = "prealloc_last_seq",
749 .fops = &osp_prealloc_last_seq_fops },
750 { .name = "prealloc_reserved",
751 .fops = &osp_prealloc_reserved_fops },
752 { .name = "timeouts",
753 .fops = &osp_timeouts_fops },
755 .fops = &osp_import_fops },
757 .fops = &osp_state_fops },
759 .fops = &osp_maxage_fops },
760 { .name = "prealloc_status",
761 .fops = &osp_pre_status_fops },
762 { .name = "sync_changes",
763 .fops = &osp_syn_changes_fops },
764 { .name = "sync_in_flight",
765 .fops = &osp_syn_in_flight_fops },
766 { .name = "sync_in_progress",
767 .fops = &osp_syn_in_prog_fops },
768 { .name = "old_sync_processed",
769 .fops = &osp_old_sync_processed_fops },
771 /* for compatibility reasons */
772 { .name = "destroys_in_flight",
773 .fops = &osp_destroys_in_flight_fops },
774 { .name = "lfsck_max_rpcs_in_flight",
775 .fops = &osp_lfsck_max_rpcs_in_flight_fops },
779 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_blksize);
780 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytestotal);
781 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytesfree);
782 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytesavail);
783 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_filestotal);
784 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_filesfree);
786 static struct lprocfs_seq_vars lprocfs_osp_osd_vars[] = {
787 { .name = "blocksize",
788 .fops = &osp_dt_blksize_fops },
789 { .name = "kbytestotal",
790 .fops = &osp_dt_kbytestotal_fops },
791 { .name = "kbytesfree",
792 .fops = &osp_dt_kbytesfree_fops },
793 { .name = "kbytesavail",
794 .fops = &osp_dt_kbytesavail_fops },
795 { .name = "filestotal",
796 .fops = &osp_dt_filestotal_fops },
797 { .name = "filesfree",
798 .fops = &osp_dt_filesfree_fops },
803 * Initialize OSP lprocfs
805 * param[in] osp OSP device
807 void osp_lprocfs_init(struct osp_device *osp)
809 struct obd_device *obd = osp->opd_obd;
810 struct proc_dir_entry *osc_proc_dir = NULL;
811 struct obd_type *type;
814 obd->obd_vars = lprocfs_osp_obd_vars;
815 if (lprocfs_obd_setup(obd) != 0)
818 rc = lprocfs_seq_add_vars(obd->obd_proc_entry, lprocfs_osp_osd_vars,
821 CERROR("%s: can't register in lprocfs, rc %d\n",
826 ptlrpc_lprocfs_register_obd(obd);
828 if (osp->opd_connect_mdt || !strstr(obd->obd_name, "osc"))
831 /* If the real OSC is present which is the case for setups
832 * with both server and clients on the same node then use
833 * the OSC's proc root */
834 type = class_search_type(LUSTRE_OSC_NAME);
835 if (type != NULL && type->typ_procroot != NULL)
836 osc_proc_dir = type->typ_procroot;
838 osc_proc_dir = obd->obd_type->typ_procsym;
840 if (osc_proc_dir == NULL)
843 /* for compatibility we link old procfs's OSC entries to osp ones */
844 osp->opd_symlink = lprocfs_add_symlink(obd->obd_name, osc_proc_dir,
845 "../osp/%s", obd->obd_name);
846 if (osp->opd_symlink == NULL)
847 CERROR("could not register OSC symlink for "
848 "/proc/fs/lustre/osp/%s.", obd->obd_name);