Whamcloud - gitweb
LU-2226 osp: dump statfs data via lprocfs
[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) 2011, 2012, Intel, Inc.
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)
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)
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)
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)
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)
292                 return 0;
293
294         return snprintf(page, count, LPU64"\n", osp->opd_pre_used_id + 1);
295 }
296
297 static int osp_rd_prealloc_last_id(char *page, char **start, off_t off,
298                                    int count, int *eof, void *data)
299 {
300         struct obd_device *obd = data;
301         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
302
303         if (osp == NULL)
304                 return 0;
305
306         return snprintf(page, count, LPU64"\n", osp->opd_pre_last_created);
307 }
308
309 static int osp_rd_prealloc_reserved(char *page, char **start, off_t off,
310                                     int count, int *eof, void *data)
311 {
312         struct obd_device *obd = data;
313         struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
314
315         if (osp == NULL)
316                 return 0;
317
318         return snprintf(page, count, LPU64"\n", osp->opd_pre_reserved);
319 }
320
321 static int osp_rd_maxage(char *page, char **start, off_t off,
322                          int count, int *eof, void *data)
323 {
324         struct obd_device       *dev = data;
325         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
326         int                      rc;
327
328         if (osp == NULL)
329                 return -EINVAL;
330
331         rc = snprintf(page, count, "%u\n", osp->opd_statfs_maxage);
332         return rc;
333 }
334
335 static int osp_wr_maxage(struct file *file, const char *buffer,
336                          unsigned long count, void *data)
337 {
338         struct obd_device       *dev = data;
339         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
340         int                      val, rc;
341
342         if (osp == NULL)
343                 return -EINVAL;
344
345         rc = lprocfs_write_helper(buffer, count, &val);
346         if (rc)
347                 return rc;
348
349         if (val < 1)
350                 return -ERANGE;
351
352         osp->opd_statfs_maxage = val;
353
354         return count;
355 }
356
357 static int osp_rd_pre_status(char *page, char **start, off_t off,
358                              int count, int *eof, void *data)
359 {
360         struct obd_device       *dev = data;
361         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
362         int                      rc;
363
364         if (osp == NULL)
365                 return -EINVAL;
366
367         rc = snprintf(page, count, "%d\n", osp->opd_pre_status);
368         return rc;
369 }
370
371 static int osp_rd_destroys_in_flight(char *page, char **start, off_t off,
372                                      int count, int *eof, void *data)
373 {
374         struct obd_device *dev = data;
375         struct osp_device *osp = lu2osp_dev(dev->obd_lu_dev);
376
377         /*
378          * This counter used to determine if OST has space returned.
379          * Now we need to wait for the following:
380          * - sync changes are zero - no llog records
381          * - sync in progress are zero - no RPCs in flight
382          */
383         return snprintf(page, count, "%lu\n",
384                         osp->opd_syn_rpc_in_progress + osp->opd_syn_changes);
385 }
386
387 static int osp_rd_old_sync_processed(char *page, char **start, off_t off,
388                                      int count, int *eof, void *data)
389 {
390         struct obd_device       *dev = data;
391         struct osp_device       *osp = lu2osp_dev(dev->obd_lu_dev);
392         int                      rc;
393
394         if (osp == NULL)
395                 return -EINVAL;
396
397         rc = snprintf(page, count, "%d\n", osp->opd_syn_prev_done);
398         return rc;
399 }
400
401 static struct lprocfs_vars lprocfs_osp_obd_vars[] = {
402         { "uuid",               lprocfs_rd_uuid, 0, 0 },
403         { "ping",               0, lprocfs_wr_ping, 0, 0, 0222 },
404         { "connect_flags",      lprocfs_rd_connect_flags, 0, 0 },
405         { "ost_server_uuid",    lprocfs_rd_server_uuid, 0, 0 },
406         { "ost_conn_uuid",      lprocfs_rd_conn_uuid, 0, 0 },
407         { "active",             osp_rd_active, osp_wr_active, 0 },
408         { "max_rpcs_in_flight", osp_rd_max_rpcs_in_flight,
409                                 osp_wr_max_rpcs_in_flight, 0 },
410         { "max_rpcs_in_progress", osp_rd_max_rpcs_in_prog,
411                                   osp_wr_max_rpcs_in_prog, 0 },
412         { "create_count",       osp_rd_create_count,
413                                 osp_wr_create_count, 0 },
414         { "max_create_count",   osp_rd_max_create_count,
415                                 osp_wr_max_create_count, 0 },
416         { "prealloc_next_id",   osp_rd_prealloc_next_id, 0, 0 },
417         { "prealloc_last_id",   osp_rd_prealloc_last_id, 0, 0 },
418         { "prealloc_reserved",  osp_rd_prealloc_reserved, 0, 0 },
419         { "timeouts",           lprocfs_rd_timeouts, 0, 0 },
420         { "import",             lprocfs_rd_import, lprocfs_wr_import, 0 },
421         { "state",              lprocfs_rd_state, 0, 0 },
422         { "maxage",             osp_rd_maxage, osp_wr_maxage, 0 },
423         { "prealloc_status",    osp_rd_pre_status, 0, 0 },
424         { "sync_changes",       osp_rd_syn_changes, 0, 0 },
425         { "sync_in_flight",     osp_rd_syn_in_flight, 0, 0 },
426         { "sync_in_progress",   osp_rd_syn_in_prog, 0, 0 },
427         { "old_sync_processed", osp_rd_old_sync_processed, 0, 0 },
428
429         /* for compatibility reasons */
430         { "destroys_in_flight", osp_rd_destroys_in_flight, 0, 0 },
431         { 0 }
432 };
433
434 static struct lprocfs_vars lprocfs_osp_osd_vars[] = {
435         { "blocksize",          lprocfs_osd_rd_blksize, 0, 0 },
436         { "kbytestotal",        lprocfs_osd_rd_kbytestotal, 0, 0 },
437         { "kbytesfree",         lprocfs_osd_rd_kbytesfree, 0, 0 },
438         { "kbytesavail",        lprocfs_osd_rd_kbytesavail, 0, 0 },
439         { "filestotal",         lprocfs_osd_rd_filestotal, 0, 0 },
440         { "filesfree",          lprocfs_osd_rd_filesfree, 0, 0 },
441         { 0 }
442 };
443
444 static struct lprocfs_vars lprocfs_osp_module_vars[] = {
445         { "num_refs",           lprocfs_rd_numrefs, 0, 0 },
446         { 0 }
447 };
448
449 void lprocfs_osp_init_vars(struct lprocfs_static_vars *lvars)
450 {
451         lvars->module_vars = lprocfs_osp_module_vars;
452         lvars->obd_vars = lprocfs_osp_obd_vars;
453 }
454
455 void osp_lprocfs_init(struct osp_device *osp)
456 {
457         struct obd_device       *obd = osp->opd_obd;
458         struct proc_dir_entry   *osc_proc_dir;
459         int                      rc;
460
461         obd->obd_proc_entry = lprocfs_register(obd->obd_name,
462                                                obd->obd_type->typ_procroot,
463                                                lprocfs_osp_osd_vars,
464                                                &osp->opd_dt_dev);
465         if (IS_ERR(obd->obd_proc_entry)) {
466                 CERROR("%s: can't register in lprocfs: %ld\n",
467                        obd->obd_name, PTR_ERR(obd->obd_proc_entry));
468                 obd->obd_proc_entry = NULL;
469                 return;
470         }
471
472         rc = lprocfs_add_vars(obd->obd_proc_entry, lprocfs_osp_obd_vars, obd);
473         if (rc) {
474                 CERROR("%s: can't register in lprocfs: %ld\n",
475                        obd->obd_name, PTR_ERR(obd->obd_proc_entry));
476                 return;
477         }
478
479         ptlrpc_lprocfs_register_obd(obd);
480
481         /* for compatibility we link old procfs's OSC entries to osp ones */
482         osc_proc_dir = lprocfs_srch(proc_lustre_root, "osc");
483         if (osc_proc_dir) {
484                 cfs_proc_dir_entry_t    *symlink = NULL;
485                 char                    *name;
486
487                 OBD_ALLOC(name, strlen(obd->obd_name) + 1);
488                 if (name == NULL)
489                         return;
490
491                 strcpy(name, obd->obd_name);
492                 if (strstr(name, "osc"))
493                         symlink = lprocfs_add_symlink(name, osc_proc_dir,
494                                                       "../osp/%s",
495                                                       obd->obd_name);
496                 OBD_FREE(name, strlen(obd->obd_name) + 1);
497                 osp->opd_symlink = symlink;
498         }
499 }
500
501 #endif /* LPROCFS */
502