Whamcloud - gitweb
118c4df6e0f1aa46db33e20b6b572d6a67db6c4a
[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_rd_active(char *page, char **start, off_t off,
49                          int count, int *eof, void *data)
50 {
51         struct obd_device       *dev = data;
52         int                      rc;
53
54         LPROCFS_CLIMP_CHECK(dev);
55         rc = snprintf(page, count, "%d\n",
56                       !dev->u.cli.cl_import->imp_deactive);
57         LPROCFS_CLIMP_EXIT(dev);
58         return rc;
59 }
60
61 static int osp_wr_active(struct file *file, const char *buffer,
62                          unsigned long count, void *data)
63 {
64         struct obd_device       *dev = data;
65         int                      val, rc;
66
67         rc = lprocfs_write_helper(buffer, count, &val);
68         if (rc)
69                 return rc;
70         if (val < 0 || val > 1)
71                 return -ERANGE;
72
73         LPROCFS_CLIMP_CHECK(dev);
74         /* opposite senses */
75         if (dev->u.cli.cl_import->imp_deactive == val)
76                 rc = ptlrpc_set_import_active(dev->u.cli.cl_import, val);
77         else
78                 CDEBUG(D_CONFIG, "activate %d: ignoring repeat request\n",
79                        val);
80
81         LPROCFS_CLIMP_EXIT(dev);
82         return count;
83 }
84
85 static int osp_rd_syn_in_flight(char *page, char **start, off_t off,
86                                 int count, int *eof, void *data)
87 {
88         struct obd_device       *dev = data;
89         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
90         int                      rc;
91
92         if (osp == NULL)
93                 return -EINVAL;
94
95         rc = snprintf(page, count, "%u\n", osp->opd_syn_rpc_in_flight);
96         return rc;
97 }
98
99 static int osp_rd_syn_in_prog(char *page, char **start, off_t off, int count,
100                               int *eof, void *data)
101 {
102         struct obd_device       *dev = data;
103         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
104         int                      rc;
105
106         if (osp == NULL)
107                 return -EINVAL;
108
109         rc = snprintf(page, count, "%u\n", osp->opd_syn_rpc_in_progress);
110         return rc;
111 }
112
113 static int osp_rd_syn_changes(char *page, char **start, off_t off,
114                               int count, int *eof, void *data)
115 {
116         struct obd_device       *dev = data;
117         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
118         int                      rc;
119
120         if (osp == NULL)
121                 return -EINVAL;
122
123         rc = snprintf(page, count, "%lu\n", osp->opd_syn_changes);
124         return rc;
125 }
126
127 static int osp_rd_max_rpcs_in_flight(char *page, char **start, off_t off,
128                                      int count, int *eof, void *data)
129 {
130         struct obd_device       *dev = data;
131         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
132         int                      rc;
133
134         if (osp == NULL)
135                 return -EINVAL;
136
137         rc = snprintf(page, count, "%u\n", osp->opd_syn_max_rpc_in_flight);
138         return rc;
139 }
140
141 static int osp_wr_max_rpcs_in_flight(struct file *file, const char *buffer,
142                                      unsigned long count, void *data)
143 {
144         struct obd_device       *dev = data;
145         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
146         int                      val, rc;
147
148         if (osp == NULL)
149                 return -EINVAL;
150
151         rc = lprocfs_write_helper(buffer, count, &val);
152         if (rc)
153                 return rc;
154
155         if (val < 1)
156                 return -ERANGE;
157
158         osp->opd_syn_max_rpc_in_flight = val;
159         return count;
160 }
161
162 static int osp_rd_max_rpcs_in_prog(char *page, char **start, off_t off,
163                                    int count, int *eof, void *data)
164 {
165         struct obd_device       *dev = data;
166         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
167         int                      rc;
168
169         if (osp == NULL)
170                 return -EINVAL;
171
172         rc = snprintf(page, count, "%u\n", osp->opd_syn_max_rpc_in_progress);
173         return rc;
174 }
175
176 static int osp_wr_max_rpcs_in_prog(struct file *file, const char *buffer,
177                                    unsigned long count, void *data)
178 {
179         struct obd_device       *dev = data;
180         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
181         int                      val, rc;
182
183         if (osp == NULL)
184                 return -EINVAL;
185
186         rc = lprocfs_write_helper(buffer, count, &val);
187         if (rc)
188                 return rc;
189
190         if (val < 1)
191                 return -ERANGE;
192
193         osp->opd_syn_max_rpc_in_progress = val;
194
195         return count;
196 }
197
198 static int osp_rd_create_count(char *page, char **start, off_t off, int count,
199                                int *eof, void *data)
200 {
201         struct obd_device *obd = data;
202         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
203
204         if (osp == NULL || osp->opd_pre == NULL)
205                 return 0;
206
207         return snprintf(page, count, "%d\n", osp->opd_pre_grow_count);
208 }
209
210 static int osp_wr_create_count(struct file *file, const char *buffer,
211                                unsigned long count, void *data)
212 {
213         struct obd_device       *obd = data;
214         struct osp_device       *osp = lu2osp_dev(obd->obd_lu_dev);
215         int                      val, rc, i;
216
217         if (osp == NULL || osp->opd_pre == NULL)
218                 return 0;
219
220         rc = lprocfs_write_helper(buffer, count, &val);
221         if (rc)
222                 return rc;
223
224         /* The MDT ALWAYS needs to limit the precreate count to
225          * OST_MAX_PRECREATE, and the constant cannot be changed
226          * because it is a value shared between the OSP and OST
227          * that is the maximum possible number of objects that will
228          * ever be handled by MDT->OST recovery processing.
229          *
230          * If the OST ever gets a request to delete more orphans,
231          * this implies that something has gone badly on the MDT
232          * and the OST will refuse to delete so much data from the
233          * filesystem as a safety measure. */
234         if (val < OST_MIN_PRECREATE || val > OST_MAX_PRECREATE)
235                 return -ERANGE;
236         if (val > osp->opd_pre_max_grow_count)
237                 return -ERANGE;
238
239         for (i = 1; (i << 1) <= val; i <<= 1)
240                 ;
241         osp->opd_pre_grow_count = i;
242
243         return count;
244 }
245
246 static int osp_rd_max_create_count(char *page, char **start, off_t off,
247                                    int count, int *eof, void *data)
248 {
249         struct obd_device *obd = data;
250         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
251
252         if (osp == NULL || osp->opd_pre == NULL)
253                 return 0;
254
255         return snprintf(page, count, "%d\n", osp->opd_pre_max_grow_count);
256 }
257
258 static int osp_wr_max_create_count(struct file *file, const char *buffer,
259                                    unsigned long count, void *data)
260 {
261         struct obd_device       *obd = data;
262         struct osp_device       *osp = lu2osp_dev(obd->obd_lu_dev);
263         int                      val, rc;
264
265         if (osp == NULL || osp->opd_pre == NULL)
266                 return 0;
267
268         rc = lprocfs_write_helper(buffer, count, &val);
269         if (rc)
270                 return rc;
271
272         if (val < 0)
273                 return -ERANGE;
274         if (val > OST_MAX_PRECREATE)
275                 return -ERANGE;
276
277         if (osp->opd_pre_grow_count > val)
278                 osp->opd_pre_grow_count = val;
279
280         osp->opd_pre_max_grow_count = val;
281
282         return count;
283 }
284
285 static int osp_rd_prealloc_next_id(char *page, char **start, off_t off,
286                                    int count, int *eof, void *data)
287 {
288         struct obd_device *obd = data;
289         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
290
291         if (osp == NULL || osp->opd_pre == NULL)
292                 return 0;
293
294         return snprintf(page, count, "%u\n",
295                         fid_oid(&osp->opd_pre_used_fid) + 1);
296 }
297
298 static int osp_rd_prealloc_last_id(char *page, char **start, off_t off,
299                                    int count, int *eof, void *data)
300 {
301         struct obd_device *obd = data;
302         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
303
304         if (osp == NULL || osp->opd_pre == NULL)
305                 return 0;
306
307         return snprintf(page, count, "%u\n",
308                         fid_oid(&osp->opd_pre_last_created_fid));
309 }
310
311 static int osp_rd_prealloc_next_seq(char *page, char **start, off_t off,
312                                     int count, int *eof, void *data)
313 {
314         struct obd_device *obd = data;
315         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
316
317         if (osp == NULL || osp->opd_pre == NULL)
318                 return 0;
319
320         return snprintf(page, count, LPX64"\n",
321                         fid_seq(&osp->opd_pre_used_fid));
322 }
323
324 static int osp_rd_prealloc_last_seq(char *page, char **start, off_t off,
325                                     int count, int *eof, void *data)
326 {
327         struct obd_device *obd = data;
328         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
329
330         if (osp == NULL || osp->opd_pre == NULL)
331                 return 0;
332
333         return snprintf(page, count, LPX64"\n",
334                         fid_seq(&osp->opd_pre_last_created_fid));
335 }
336
337 static int osp_rd_prealloc_reserved(char *page, char **start, off_t off,
338                                     int count, int *eof, void *data)
339 {
340         struct obd_device *obd = data;
341         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
342
343         if (osp == NULL || osp->opd_pre == NULL)
344                 return 0;
345
346         return snprintf(page, count, LPU64"\n", osp->opd_pre_reserved);
347 }
348
349 static int osp_rd_maxage(char *page, char **start, off_t off,
350                          int count, int *eof, void *data)
351 {
352         struct obd_device       *dev = data;
353         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
354         int                      rc;
355
356         if (osp == NULL)
357                 return -EINVAL;
358
359         rc = snprintf(page, count, "%u\n", osp->opd_statfs_maxage);
360         return rc;
361 }
362
363 static int osp_wr_maxage(struct file *file, const char *buffer,
364                          unsigned long count, void *data)
365 {
366         struct obd_device       *dev = data;
367         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
368         int                      val, rc;
369
370         if (osp == NULL)
371                 return -EINVAL;
372
373         rc = lprocfs_write_helper(buffer, count, &val);
374         if (rc)
375                 return rc;
376
377         if (val < 1)
378                 return -ERANGE;
379
380         osp->opd_statfs_maxage = val;
381
382         return count;
383 }
384
385 static int osp_rd_pre_status(char *page, char **start, off_t off,
386                              int count, int *eof, void *data)
387 {
388         struct obd_device       *dev = data;
389         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
390         int                      rc;
391
392         if (osp == NULL || osp->opd_pre == NULL)
393                 return -EINVAL;
394
395         rc = snprintf(page, count, "%d\n", osp->opd_pre_status);
396         return rc;
397 }
398
399 static int osp_rd_destroys_in_flight(char *page, char **start, off_t off,
400                                      int count, int *eof, void *data)
401 {
402         struct obd_device *dev = data;
403         struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
404
405         if (osp == NULL)
406                 return -EINVAL;
407
408         /*
409          * This counter used to determine if OST has space returned.
410          * Now we need to wait for the following:
411          * - sync changes are zero - no llog records
412          * - sync in progress are zero - no RPCs in flight
413          */
414         return snprintf(page, count, "%lu\n",
415                         osp->opd_syn_rpc_in_progress + osp->opd_syn_changes);
416 }
417
418 static int osp_rd_old_sync_processed(char *page, char **start, off_t off,
419                                      int count, int *eof, void *data)
420 {
421         struct obd_device       *dev = data;
422         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
423         int                      rc;
424
425         if (osp == NULL)
426                 return -EINVAL;
427
428         rc = snprintf(page, count, "%d\n", osp->opd_syn_prev_done);
429         return rc;
430 }
431
432 static int osp_rd_lfsck_max_rpcs_in_flight(char *page, char **start, off_t off,
433                                            int count, int *eof, void *data)
434 {
435         struct obd_device *dev = data;
436         __u32 max;
437         int rc;
438
439         *eof = 1;
440         max = obd_get_max_rpcs_in_flight(&dev->u.cli);
441         rc = snprintf(page, count, "%u\n", max);
442
443         return rc;
444 }
445
446 static int osp_wr_lfsck_max_rpcs_in_flight(struct file *file,
447                                            const char *buffer,
448                                            unsigned long count, void *data)
449 {
450         struct obd_device *dev = data;
451         int val;
452         int rc;
453
454         rc = lprocfs_write_helper(buffer, count, &val);
455         if (rc == 0)
456                 rc = obd_set_max_rpcs_in_flight(&dev->u.cli, val);
457
458         if (rc != 0)
459                 count = rc;
460
461         return count;
462 }
463
464 static struct lprocfs_vars lprocfs_osp_obd_vars[] = {
465         { "uuid",               lprocfs_rd_uuid, 0, 0 },
466         { "ping",               0, lprocfs_wr_ping, 0, 0, 0222 },
467         { "connect_flags",      lprocfs_rd_connect_flags, 0, 0 },
468         { "ost_server_uuid",    lprocfs_rd_server_uuid, 0, 0 },
469         { "ost_conn_uuid",      lprocfs_rd_conn_uuid, 0, 0 },
470         { "active",             osp_rd_active, osp_wr_active, 0 },
471         { "max_rpcs_in_flight", osp_rd_max_rpcs_in_flight,
472                                 osp_wr_max_rpcs_in_flight, 0 },
473         { "max_rpcs_in_progress", osp_rd_max_rpcs_in_prog,
474                                   osp_wr_max_rpcs_in_prog, 0 },
475         { "create_count",       osp_rd_create_count,
476                                 osp_wr_create_count, 0 },
477         { "max_create_count",   osp_rd_max_create_count,
478                                 osp_wr_max_create_count, 0 },
479         { "prealloc_next_id",   osp_rd_prealloc_next_id, 0, 0 },
480         { "prealloc_next_seq",  osp_rd_prealloc_next_seq, 0, 0 },
481         { "prealloc_last_id",   osp_rd_prealloc_last_id,  0, 0 },
482         { "prealloc_last_seq",  osp_rd_prealloc_last_seq, 0, 0 },
483         { "prealloc_reserved",  osp_rd_prealloc_reserved, 0, 0 },
484         { "timeouts",           lprocfs_rd_timeouts, 0, 0 },
485         { "import",             lprocfs_rd_import, lprocfs_wr_import, 0 },
486         { "state",              lprocfs_rd_state, 0, 0 },
487         { "maxage",             osp_rd_maxage, osp_wr_maxage, 0 },
488         { "prealloc_status",    osp_rd_pre_status, 0, 0 },
489         { "sync_changes",       osp_rd_syn_changes, 0, 0 },
490         { "sync_in_flight",     osp_rd_syn_in_flight, 0, 0 },
491         { "sync_in_progress",   osp_rd_syn_in_prog, 0, 0 },
492         { "old_sync_processed", osp_rd_old_sync_processed, 0, 0 },
493
494         /* for compatibility reasons */
495         { "destroys_in_flight", osp_rd_destroys_in_flight, 0, 0 },
496         { "lfsck_max_rpcs_in_flight", osp_rd_lfsck_max_rpcs_in_flight,
497                                       osp_wr_lfsck_max_rpcs_in_flight, 0 },
498         { 0 }
499 };
500
501 static struct lprocfs_vars lprocfs_osp_osd_vars[] = {
502         { "blocksize",          lprocfs_dt_rd_blksize, 0, 0 },
503         { "kbytestotal",        lprocfs_dt_rd_kbytestotal, 0, 0 },
504         { "kbytesfree",         lprocfs_dt_rd_kbytesfree, 0, 0 },
505         { "kbytesavail",        lprocfs_dt_rd_kbytesavail, 0, 0 },
506         { "filestotal",         lprocfs_dt_rd_filestotal, 0, 0 },
507         { "filesfree",          lprocfs_dt_rd_filesfree, 0, 0 },
508         { 0 }
509 };
510
511 static struct lprocfs_vars lprocfs_osp_module_vars[] = {
512         { "num_refs",           lprocfs_rd_numrefs, 0, 0 },
513         { 0 }
514 };
515
516 void lprocfs_osp_init_vars(struct lprocfs_static_vars *lvars)
517 {
518         lvars->module_vars = lprocfs_osp_module_vars;
519         lvars->obd_vars = lprocfs_osp_obd_vars;
520 }
521
522 void osp_lprocfs_init(struct osp_device *osp)
523 {
524         struct obd_device       *obd = osp->opd_obd;
525         struct proc_dir_entry   *osc_proc_dir;
526         int                      rc;
527
528         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
529                                                obd->obd_type->typ_procroot,
530                                                lprocfs_osp_osd_vars,
531                                                &osp->opd_dt_dev);
532         if (IS_ERR(obd->obd_proc_entry)) {
533                 CERROR("%s: can't register in lprocfs: %ld\n",
534                        obd->obd_name, PTR_ERR(obd->obd_proc_entry));
535                 obd->obd_proc_entry = NULL;
536                 return;
537         }
538
539         rc = lprocfs_add_vars(obd->obd_proc_entry, lprocfs_osp_obd_vars, obd);
540         if (rc) {
541                 CERROR("%s: can't register in lprocfs: %ld\n",
542                        obd->obd_name, PTR_ERR(obd->obd_proc_entry));
543                 return;
544         }
545
546         ptlrpc_lprocfs_register_obd(obd);
547
548         /* for compatibility we link old procfs's OSC entries to osp ones */
549         if (!osp->opd_connect_mdt) {
550                 osc_proc_dir = lprocfs_srch(proc_lustre_root, "osc");
551                 if (osc_proc_dir) {
552                         cfs_proc_dir_entry_t    *symlink = NULL;
553                         char                    *name;
554
555                         OBD_ALLOC(name, strlen(obd->obd_name) + 1);
556                         if (name == NULL)
557                                 return;
558
559                         strcpy(name, obd->obd_name);
560                         if (strstr(name, "osc"))
561                                 symlink = lprocfs_add_symlink(name,
562                                                 osc_proc_dir, "../osp/%s",
563                                                 obd->obd_name);
564                         OBD_FREE(name, strlen(obd->obd_name) + 1);
565                         osp->opd_symlink = symlink;
566                 }
567         }
568 }
569
570 #endif /* LPROCFS */
571