Whamcloud - gitweb
4565f9f081c770b77455fc77a238c2655ffa2b60
[fs/lustre-release.git] / lustre / osp / lproc_osp.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
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.
9  *
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).
15  *
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
19  *
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
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, 2013, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/osp/lproc_osp.c
37  *
38  * Lustre OST Proxy Device, procfs functions
39  *
40  * Author: Alex Zhuravlev <alexey.zhuravlev@intel.com>
41  */
42
43 #define DEBUG_SUBSYSTEM S_CLASS
44
45 #include "osp_internal.h"
46
47 #ifdef LPROCFS
48 static int osp_active_seq_show(struct seq_file *m, void *data)
49 {
50         struct obd_device       *dev = m->private;
51         int                      rc;
52
53         LPROCFS_CLIMP_CHECK(dev);
54         rc = seq_printf(m, "%d\n", !dev->u.cli.cl_import->imp_deactive);
55         LPROCFS_CLIMP_EXIT(dev);
56         return rc;
57 }
58
59 static ssize_t
60 osp_active_seq_write(struct file *file, const char *buffer,
61                         size_t count, loff_t *off)
62 {
63         struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
64         int                val, rc;
65
66         rc = lprocfs_write_helper(buffer, count, &val);
67         if (rc)
68                 return rc;
69         if (val < 0 || val > 1)
70                 return -ERANGE;
71
72         LPROCFS_CLIMP_CHECK(dev);
73         /* opposite senses */
74         if (dev->u.cli.cl_import->imp_deactive == val)
75                 rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
76         else
77                 CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n",
78                        val);
79
80         LPROCFS_CLIMP_EXIT(dev);
81         return count;
82 }
83 LPROC_SEQ_FOPS(osp_active);
84
85 static int osp_syn_in_flight_seq_show(struct seq_file *m, void *data)
86 {
87         struct obd_device       *dev = m->private;
88         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
89
90         if (osp == NULL)
91                 return -EINVAL;
92
93         return seq_printf(m, "%u\n", osp->opd_syn_rpc_in_flight);
94 }
95 LPROC_SEQ_FOPS_RO(osp_syn_in_flight);
96
97 static int osp_syn_in_prog_seq_show(struct seq_file *m, void *data)
98 {
99         struct obd_device       *dev = m->private;
100         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
101
102         if (osp == NULL)
103                 return -EINVAL;
104
105         return seq_printf(m, "%u\n", osp->opd_syn_rpc_in_progress);
106 }
107 LPROC_SEQ_FOPS_RO(osp_syn_in_prog);
108
109 static int osp_syn_changes_seq_show(struct seq_file *m, void *data)
110 {
111         struct obd_device       *dev = m->private;
112         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
113
114         if (osp == NULL)
115                 return -EINVAL;
116
117         return seq_printf(m, "%lu\n", osp->opd_syn_changes);
118 }
119 LPROC_SEQ_FOPS_RO(osp_syn_changes);
120
121 static int osp_max_rpcs_in_flight_seq_show(struct seq_file *m, void *data)
122 {
123         struct obd_device       *dev = m->private;
124         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
125
126         if (osp == NULL)
127                 return -EINVAL;
128
129         return seq_printf(m, "%u\n", osp->opd_syn_max_rpc_in_flight);
130 }
131
132 static ssize_t
133 osp_max_rpcs_in_flight_seq_write(struct file *file, const char *buffer,
134                                 size_t count, loff_t *off)
135 {
136         struct obd_device       *dev = ((struct seq_file *)file->private_data)->private;
137         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
138         int                      val, rc;
139
140         if (osp == NULL)
141                 return -EINVAL;
142
143         rc = lprocfs_write_helper(buffer, count, &val);
144         if (rc)
145                 return rc;
146
147         if (val < 1)
148                 return -ERANGE;
149
150         osp->opd_syn_max_rpc_in_flight = val;
151         return count;
152 }
153 LPROC_SEQ_FOPS(osp_max_rpcs_in_flight);
154
155 static int osp_max_rpcs_in_prog_seq_show(struct seq_file *m, void *data)
156 {
157         struct obd_device       *dev = m->private;
158         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
159
160         if (osp == NULL)
161                 return -EINVAL;
162
163         return seq_printf(m, "%u\n", osp->opd_syn_max_rpc_in_progress);
164 }
165
166 static ssize_t
167 osp_max_rpcs_in_prog_seq_write(struct file *file, const char *buffer,
168                                 size_t count, loff_t *off)
169 {
170         struct obd_device       *dev = ((struct seq_file *)file->private_data)->private;
171         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
172         int                      val, rc;
173
174         if (osp == NULL)
175                 return -EINVAL;
176
177         rc = lprocfs_write_helper(buffer, count, &val);
178         if (rc)
179                 return rc;
180
181         if (val < 1)
182                 return -ERANGE;
183
184         osp->opd_syn_max_rpc_in_progress = val;
185
186         return count;
187 }
188 LPROC_SEQ_FOPS(osp_max_rpcs_in_prog);
189
190 static int osp_create_count_seq_show(struct seq_file *m, void *data)
191 {
192         struct obd_device *obd = m->private;
193         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
194
195         if (osp == NULL || osp->opd_pre == NULL)
196                 return 0;
197
198         return seq_printf(m, "%d\n", osp->opd_pre_grow_count);
199 }
200
201 static ssize_t
202 osp_create_count_seq_write(struct file *file, const char *buffer,
203                                 size_t count, loff_t *off)
204 {
205         struct obd_device       *obd = ((struct seq_file *)file->private_data)->private;
206         struct osp_device       *osp = lu2osp_dev(obd->obd_lu_dev);
207         int                      val, rc, i;
208
209         if (osp == NULL || osp->opd_pre == NULL)
210                 return 0;
211
212         rc = lprocfs_write_helper(buffer, count, &val);
213         if (rc)
214                 return rc;
215
216         /* The MDT ALWAYS needs to limit the precreate count to
217          * OST_MAX_PRECREATE, and the constant cannot be changed
218          * because it is a value shared between the OSP and OST
219          * that is the maximum possible number of objects that will
220          * ever be handled by MDT->OST recovery processing.
221          *
222          * If the OST ever gets a request to delete more orphans,
223          * this implies that something has gone badly on the MDT
224          * and the OST will refuse to delete so much data from the
225          * filesystem as a safety measure. */
226         if (val < OST_MIN_PRECREATE || val > OST_MAX_PRECREATE)
227                 return -ERANGE;
228         if (val > osp->opd_pre_max_grow_count)
229                 return -ERANGE;
230
231         for (i = 1; (i << 1) <= val; i <<= 1)
232                 ;
233         osp->opd_pre_grow_count = i;
234
235         return count;
236 }
237 LPROC_SEQ_FOPS(osp_create_count);
238
239 static int osp_max_create_count_seq_show(struct seq_file *m, void *data)
240 {
241         struct obd_device *obd = m->private;
242         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
243
244         if (osp == NULL || osp->opd_pre == NULL)
245                 return 0;
246
247         return seq_printf(m, "%d\n", osp->opd_pre_max_grow_count);
248 }
249
250 static ssize_t
251 osp_max_create_count_seq_write(struct file *file, const char *buffer,
252                                 size_t count, loff_t *off)
253 {
254         struct obd_device       *obd = ((struct seq_file *)file->private_data)->private;
255         struct osp_device       *osp = lu2osp_dev(obd->obd_lu_dev);
256         int                      val, rc;
257
258         if (osp == NULL || osp->opd_pre == NULL)
259                 return 0;
260
261         rc = lprocfs_write_helper(buffer, count, &val);
262         if (rc)
263                 return rc;
264
265         if (val < 0)
266                 return -ERANGE;
267         if (val > OST_MAX_PRECREATE)
268                 return -ERANGE;
269
270         if (osp->opd_pre_grow_count > val)
271                 osp->opd_pre_grow_count = val;
272
273         osp->opd_pre_max_grow_count = val;
274
275         return count;
276 }
277 LPROC_SEQ_FOPS(osp_max_create_count);
278
279 static int osp_prealloc_next_id_seq_show(struct seq_file *m, void *data)
280 {
281         struct obd_device *obd = m->private;
282         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
283
284         if (osp == NULL || osp->opd_pre == NULL)
285                 return 0;
286
287         return seq_printf(m, "%u\n", fid_oid(&osp->opd_pre_used_fid) + 1);
288 }
289 LPROC_SEQ_FOPS_RO(osp_prealloc_next_id);
290
291 static int osp_prealloc_last_id_seq_show(struct seq_file *m, void *data)
292 {
293         struct obd_device *obd = m->private;
294         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
295
296         if (osp == NULL || osp->opd_pre == NULL)
297                 return 0;
298
299         return seq_printf(m, "%u\n", fid_oid(&osp->opd_pre_last_created_fid));
300 }
301 LPROC_SEQ_FOPS_RO(osp_prealloc_last_id);
302
303 static int osp_prealloc_next_seq_seq_show(struct seq_file *m, void *data)
304 {
305         struct obd_device *obd = m->private;
306         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
307
308         if (osp == NULL || osp->opd_pre == NULL)
309                 return 0;
310
311         return seq_printf(m, LPX64"\n", fid_seq(&osp->opd_pre_used_fid));
312 }
313 LPROC_SEQ_FOPS_RO(osp_prealloc_next_seq);
314
315 static int osp_prealloc_last_seq_seq_show(struct seq_file *m, void *data)
316 {
317         struct obd_device *obd = m->private;
318         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
319
320         if (osp == NULL || osp->opd_pre == NULL)
321                 return 0;
322
323         return seq_printf(m, LPX64"\n",
324                         fid_seq(&osp->opd_pre_last_created_fid));
325 }
326 LPROC_SEQ_FOPS_RO(osp_prealloc_last_seq);
327
328 static int osp_prealloc_reserved_seq_show(struct seq_file *m, void *data)
329 {
330         struct obd_device *obd = m->private;
331         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
332
333         if (osp == NULL || osp->opd_pre == NULL)
334                 return 0;
335
336         return seq_printf(m, LPU64"\n", osp->opd_pre_reserved);
337 }
338 LPROC_SEQ_FOPS_RO(osp_prealloc_reserved);
339
340 static int osp_maxage_seq_show(struct seq_file *m, void *data)
341 {
342         struct obd_device       *dev = m->private;
343         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
344
345         if (osp == NULL)
346                 return -EINVAL;
347
348         return seq_printf(m, "%u\n", osp->opd_statfs_maxage);
349 }
350
351 static ssize_t
352 osp_maxage_seq_write(struct file *file, const char *buffer,
353                         size_t count, loff_t *off)
354 {
355         struct obd_device       *dev = ((struct seq_file *)file->private_data)->private;
356         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
357         int                      val, rc;
358
359         if (osp == NULL)
360                 return -EINVAL;
361
362         rc = lprocfs_write_helper(buffer, count, &val);
363         if (rc)
364                 return rc;
365
366         if (val < 1)
367                 return -ERANGE;
368
369         osp->opd_statfs_maxage = val;
370
371         return count;
372 }
373 LPROC_SEQ_FOPS(osp_maxage);
374
375 static int osp_pre_status_seq_show(struct seq_file *m, void *data)
376 {
377         struct obd_device       *dev = m->private;
378         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
379
380         if (osp == NULL || osp->opd_pre == NULL)
381                 return -EINVAL;
382
383         return seq_printf(m, "%d\n", osp->opd_pre_status);
384 }
385 LPROC_SEQ_FOPS_RO(osp_pre_status);
386
387 static int osp_destroys_in_flight_seq_show(struct seq_file *m, void *data)
388 {
389         struct obd_device *dev = m->private;
390         struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
391
392         if (osp == NULL)
393                 return -EINVAL;
394
395         /*
396          * This counter used to determine if OST has space returned.
397          * Now we need to wait for the following:
398          * - sync changes are zero - no llog records
399          * - sync in progress are zero - no RPCs in flight
400          */
401         return seq_printf(m, "%lu\n",
402                         osp->opd_syn_rpc_in_progress + osp->opd_syn_changes);
403 }
404 LPROC_SEQ_FOPS_RO(osp_destroys_in_flight);
405
406 static int osp_old_sync_processed_seq_show(struct seq_file *m, void *data)
407 {
408         struct obd_device       *dev = m->private;
409         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
410
411         if (osp == NULL)
412                 return -EINVAL;
413
414         return seq_printf(m, "%d\n", osp->opd_syn_prev_done);
415 }
416 LPROC_SEQ_FOPS_RO(osp_old_sync_processed);
417
418 LPROC_SEQ_FOPS_WO_TYPE(osp, ping);
419 LPROC_SEQ_FOPS_RO_TYPE(osp, uuid);
420 LPROC_SEQ_FOPS_RO_TYPE(osp, connect_flags);
421 LPROC_SEQ_FOPS_RO_TYPE(osp, server_uuid);
422 LPROC_SEQ_FOPS_RO_TYPE(osp, conn_uuid);
423
424 static int osp_max_pages_per_rpc_seq_show(struct seq_file *m, void *v)
425 {
426         return lprocfs_obd_max_pages_per_rpc_seq_show(m, m->private);
427 }
428 LPROC_SEQ_FOPS_RO(osp_max_pages_per_rpc);
429 LPROC_SEQ_FOPS_RO_TYPE(osp, timeouts);
430
431 LPROC_SEQ_FOPS_RW_TYPE(osp, import);
432 LPROC_SEQ_FOPS_RO_TYPE(osp, state);
433
434 static struct lprocfs_seq_vars lprocfs_osp_obd_vars[] = {
435         { .name =       "uuid",
436           .fops =       &osp_uuid_fops                  },
437         { .name =       "ping",
438           .fops =       &osp_ping_fops,
439           .proc_mode =  0222                            },
440         { .name =       "connect_flags",
441           .fops =       &osp_connect_flags_fops         },
442         { .name =       "ost_server_uuid",
443           .fops =       &osp_server_uuid_fops           },
444         { .name =       "ost_conn_uuid",
445           .fops =       &osp_conn_uuid_fops             },
446         { .name =       "active",
447           .fops =       &osp_active_fops                },
448         { .name =       "max_rpcs_in_flight",
449           .fops =       &osp_max_rpcs_in_flight_fops    },
450         { .name =       "max_rpcs_in_progress",
451           .fops =       &osp_max_rpcs_in_prog_fops      },
452         { .name =       "create_count",
453           .fops =       &osp_create_count_fops          },
454         { .name =       "max_create_count",
455           .fops =       &osp_max_create_count_fops      },
456         { .name =       "prealloc_next_id",
457           .fops =       &osp_prealloc_next_id_fops      },
458         { .name =       "prealloc_next_seq",
459           .fops =       &osp_prealloc_next_seq_fops     },
460         { .name =       "prealloc_last_id",
461           .fops =       &osp_prealloc_last_id_fops      },
462         { .name =       "prealloc_last_seq",
463           .fops =       &osp_prealloc_last_seq_fops     },
464         { .name =       "prealloc_reserved",
465           .fops =       &osp_prealloc_reserved_fops     },
466         { .name =       "timeouts",
467           .fops =       &osp_timeouts_fops              },
468         { .name =       "import",
469           .fops =       &osp_import_fops                },
470         { .name =       "state",
471           .fops =       &osp_state_fops                 },
472         { .name =       "maxage",
473           .fops =       &osp_maxage_fops                },
474         { .name =       "prealloc_status",
475           .fops =       &osp_pre_status_fops            },
476         { .name =       "sync_changes",
477           .fops =       &osp_syn_changes_fops           },
478         { .name =       "sync_in_flight",
479           .fops =       &osp_syn_in_flight_fops         },
480         { .name =       "sync_in_progress",
481           .fops =       &osp_syn_in_prog_fops           },
482         { .name =       "old_sync_processed",
483           .fops =       &osp_old_sync_processed_fops    },
484
485         /* for compatibility reasons */
486         { .name =       "destroys_in_flight",
487           .fops =       &osp_destroys_in_flight_fops    },
488         { 0 }
489 };
490
491 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_blksize);
492 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytestotal);
493 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytesfree);
494 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_kbytesavail);
495 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_filestotal);
496 LPROC_SEQ_FOPS_RO_TYPE(osp, dt_filesfree);
497
498 static struct lprocfs_seq_vars lprocfs_osp_osd_vars[] = {
499         { .name =       "blocksize",
500           .fops =       &osp_dt_blksize_fops            },
501         { .name =       "kbytestotal",
502           .fops =       &osp_dt_kbytestotal_fops        },
503         { .name =       "kbytesfree",
504           .fops =       &osp_dt_kbytesfree_fops         },
505         { .name =       "kbytesavail",
506           .fops =       &osp_dt_kbytesavail_fops        },
507         { .name =       "filestotal",
508           .fops =       &osp_dt_filestotal_fops         },
509         { .name =       "filesfree",
510           .fops =       &osp_dt_filesfree_fops          },
511         { 0 }
512 };
513
514 void osp_lprocfs_init(struct osp_device *osp)
515 {
516         struct obd_device       *obd = osp->opd_obd;
517         struct proc_dir_entry   *osc_proc_dir;
518         int                      rc;
519
520         obd->obd_proc_entry = lprocfs_seq_register(obd->obd_name,
521                                                obd->obd_type->typ_procroot,
522                                                lprocfs_osp_osd_vars,
523                                                &osp->opd_dt_dev);
524         if (IS_ERR(obd->obd_proc_entry)) {
525                 CERROR("%s: can't register in lprocfs: %ld\n",
526                        obd->obd_name, PTR_ERR(obd->obd_proc_entry));
527                 obd->obd_proc_entry = NULL;
528                 return;
529         }
530
531         rc = lprocfs_seq_add_vars(obd->obd_proc_entry, lprocfs_osp_obd_vars, obd);
532         if (rc) {
533                 CERROR("%s: can't register in lprocfs: %ld\n",
534                        obd->obd_name, PTR_ERR(obd->obd_proc_entry));
535                 return;
536         }
537         obd->obd_vars = lprocfs_osp_obd_vars;
538
539         ptlrpc_lprocfs_register_obd(obd);
540
541         if (osp->opd_connect_mdt)
542                 return;
543
544         /* for compatibility we link old procfs's OSC entries to osp ones */
545         osc_proc_dir = obd->obd_proc_private;
546         if (osc_proc_dir == NULL) {
547                 cfs_proc_dir_entry_t    *symlink = NULL;
548                 struct obd_type         *type;
549                 char                    *name;
550
551                 type = class_search_type(LUSTRE_OSC_NAME);
552                 if (type == NULL) {
553                         osc_proc_dir = lprocfs_seq_register("osc",
554                                                         proc_lustre_root,
555                                                         NULL, NULL);
556                         if (IS_ERR(osc_proc_dir)) {
557                                 CERROR("osp: can't create compat entry \"osc\": %d\n",
558                                         (int) PTR_ERR(osc_proc_dir));
559                         } else {
560                                 obd->obd_proc_private = osc_proc_dir;
561                         }
562                 } else {
563                         osc_proc_dir = type->typ_procroot;
564                 }
565
566                 OBD_ALLOC(name, strlen(obd->obd_name) + 1);
567                 if (name == NULL)
568                         return;
569
570                 strcpy(name, obd->obd_name);
571                 if (strstr(name, "osc")) {
572                         symlink = lprocfs_add_symlink(name, osc_proc_dir,
573                                                         "../osp/%s",
574                                                         obd->obd_name);
575                         OBD_FREE(name, strlen(obd->obd_name) + 1);
576                         if (symlink == NULL) {
577                                 CERROR("could not register OSC symlink for "
578                                         "/proc/fs/lustre/osp/%s.",
579                                         obd->obd_name);
580                                 lprocfs_remove(&osc_proc_dir);
581                         } else {
582                                 osp->opd_symlink = symlink;
583                         }
584                 }
585         }
586 }
587
588 #endif /* LPROCFS */
589