Whamcloud - gitweb
fca6a8c6feece009186bdaf17a463031c62e829a
[fs/lustre-release.git] / lustre / lov / lproc_lov.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.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  * Lustre is a trademark of Sun Microsystems, Inc.
31  */
32 #define DEBUG_SUBSYSTEM S_CLASS
33
34 #include <linux/version.h>
35 #include <asm/statfs.h>
36 #include <lprocfs_status.h>
37 #include <obd_class.h>
38 #include <uapi/linux/lustre/lustre_param.h>
39 #include "lov_internal.h"
40
41 static int lov_stripesize_seq_show(struct seq_file *m, void *v)
42 {
43         struct obd_device *dev = (struct obd_device *)m->private;
44         struct lov_desc *desc;
45
46         LASSERT(dev != NULL);
47         desc = &dev->u.lov.desc;
48
49         seq_printf(m, "%llu\n", desc->ld_default_stripe_size);
50         return 0;
51 }
52
53 static ssize_t lov_stripesize_seq_write(struct file *file,
54                                         const char __user *buffer,
55                                         size_t count, loff_t *off)
56 {
57         struct obd_device *dev = ((struct seq_file *)file->private_data)->private;
58         struct lov_desc *desc;
59         s64 val;
60         int rc;
61
62         LASSERT(dev != NULL);
63         desc = &dev->u.lov.desc;
64         rc = lprocfs_str_with_units_to_s64(buffer, count, &val, '1');
65         if (rc)
66                 return rc;
67         if (val < 0)
68                 return -ERANGE;
69
70         lov_fix_desc_stripe_size(&val);
71         desc->ld_default_stripe_size = val;
72
73         return count;
74 }
75 LPROC_SEQ_FOPS(lov_stripesize);
76
77 static ssize_t stripeoffset_show(struct kobject *kobj, struct attribute *attr,
78                                  char *buf)
79 {
80         struct obd_device *dev = container_of(kobj, struct obd_device,
81                                               obd_kset.kobj);
82         struct lov_desc *desc = &dev->u.lov.desc;
83
84         return sprintf(buf, "%lld\n", desc->ld_default_stripe_offset);
85 }
86
87 static ssize_t stripeoffset_store(struct kobject *kobj, struct attribute *attr,
88                                   const char *buf, size_t count)
89 {
90         struct obd_device *dev = container_of(kobj, struct obd_device,
91                                               obd_kset.kobj);
92         struct lov_desc *desc = &dev->u.lov.desc;
93         long val;
94         int rc;
95
96         rc = kstrtol(buf, 0, &val);
97         if (rc)
98                 return rc;
99         if (val < -1 || val > LOV_MAX_STRIPE_COUNT)
100                 return -ERANGE;
101
102         desc->ld_default_stripe_offset = val;
103
104         return count;
105 }
106 LUSTRE_RW_ATTR(stripeoffset);
107
108 static ssize_t stripetype_show(struct kobject *kobj, struct attribute *attr,
109                                char *buf)
110 {
111         struct obd_device *dev = container_of(kobj, struct obd_device,
112                                               obd_kset.kobj);
113         struct lov_desc *desc = &dev->u.lov.desc;
114
115         return sprintf(buf, "%u\n", desc->ld_pattern);
116 }
117
118 static ssize_t stripetype_store(struct kobject *kobj, struct attribute *attr,
119                                 const char *buffer, size_t count)
120 {
121         struct obd_device *dev = container_of(kobj, struct obd_device,
122                                               obd_kset.kobj);
123         struct lov_desc *desc = &dev->u.lov.desc;
124         u32 pattern;
125         int rc;
126
127         rc = kstrtouint(buffer, 0, &pattern);
128         if (rc)
129                 return rc;
130
131         lov_fix_desc_pattern(&pattern);
132         desc->ld_pattern = pattern;
133
134         return count;
135 }
136 LUSTRE_RW_ATTR(stripetype);
137
138 static ssize_t stripecount_show(struct kobject *kobj, struct attribute *attr,
139                                 char *buf)
140 {
141         struct obd_device *dev = container_of(kobj, struct obd_device,
142                                               obd_kset.kobj);
143         struct lov_desc *desc = &dev->u.lov.desc;
144
145         return sprintf(buf, "%d\n",
146                        (__s16)(desc->ld_default_stripe_count + 1) - 1);
147 }
148
149 static ssize_t stripecount_store(struct kobject *kobj, struct attribute *attr,
150                                  const char *buffer, size_t count)
151 {
152         struct obd_device *dev = container_of(kobj, struct obd_device,
153                                               obd_kset.kobj);
154         struct lov_desc *desc = &dev->u.lov.desc;
155         int stripe_count;
156         int rc;
157
158         rc = kstrtoint(buffer, 0, &stripe_count);
159         if (rc)
160                 return rc;
161
162         if (stripe_count < -1)
163                 return -ERANGE;
164
165         lov_fix_desc_stripe_count(&stripe_count);
166         desc->ld_default_stripe_count = stripe_count;
167
168         return count;
169 }
170 LUSTRE_RW_ATTR(stripecount);
171
172 static ssize_t numobd_show(struct kobject *kobj, struct attribute *attr,
173                            char *buf)
174 {
175         struct obd_device *dev = container_of(kobj, struct obd_device,
176                                               obd_kset.kobj);
177         struct lov_desc *desc = &dev->u.lov.desc;
178
179         return sprintf(buf, "%u\n", desc->ld_tgt_count);
180 }
181 LUSTRE_RO_ATTR(numobd);
182
183 static ssize_t activeobd_show(struct kobject *kobj, struct attribute *attr,
184                               char *buf)
185 {
186         struct obd_device *dev = container_of(kobj, struct obd_device,
187                                               obd_kset.kobj);
188         struct lov_desc *desc = &dev->u.lov.desc;
189
190         return sprintf(buf, "%u\n", desc->ld_active_tgt_count);
191 }
192 LUSTRE_RO_ATTR(activeobd);
193
194 static ssize_t desc_uuid_show(struct kobject *kobj, struct attribute *attr,
195                               char *buf)
196 {
197         struct obd_device *dev = container_of(kobj, struct obd_device,
198                                               obd_kset.kobj);
199         struct lov_desc *desc = &dev->u.lov.desc;
200
201         return sprintf(buf, "%s\n", desc->ld_uuid.uuid);
202 }
203 LUSTRE_RO_ATTR(desc_uuid);
204
205 #ifdef CONFIG_PROC_FS
206 static void *lov_tgt_seq_start(struct seq_file *p, loff_t *pos)
207 {
208         struct obd_device *dev = p->private;
209         struct lov_obd *lov = &dev->u.lov;
210
211         while (*pos < lov->desc.ld_tgt_count) {
212                 if (lov->lov_tgts[*pos])
213                         return lov->lov_tgts[*pos];
214                 ++*pos;
215         }
216         return NULL;
217 }
218
219 static void lov_tgt_seq_stop(struct seq_file *p, void *v)
220 {
221 }
222
223 static void *lov_tgt_seq_next(struct seq_file *p, void *v, loff_t *pos)
224 {
225         struct obd_device *dev = p->private;
226         struct lov_obd *lov = &dev->u.lov;
227
228         while (++*pos < lov->desc.ld_tgt_count) {
229                 if (lov->lov_tgts[*pos])
230                         return lov->lov_tgts[*pos];
231         }
232         return NULL;
233 }
234
235 static int lov_tgt_seq_show(struct seq_file *p, void *v)
236 {
237         struct lov_tgt_desc *tgt = v;
238
239         seq_printf(p, "%d: %s %sACTIVE\n", tgt->ltd_index,
240                    obd_uuid2str(&tgt->ltd_uuid),
241                    tgt->ltd_active ? "" : "IN");
242         return 0;
243 }
244
245 static const struct seq_operations lov_tgt_sops = {
246         .start = lov_tgt_seq_start,
247         .stop = lov_tgt_seq_stop,
248         .next = lov_tgt_seq_next,
249         .show = lov_tgt_seq_show,
250 };
251
252 static int lov_target_seq_open(struct inode *inode, struct file *file)
253 {
254         struct seq_file *seq;
255         int rc;
256
257         rc = seq_open(file, &lov_tgt_sops);
258         if (rc)
259                 return rc;
260
261         seq = file->private_data;
262         seq->private = PDE_DATA(inode);
263         return 0;
264 }
265
266 struct lprocfs_vars lprocfs_lov_obd_vars[] = {
267         { .name =       "stripesize",
268           .fops =       &lov_stripesize_fops    },
269         { NULL }
270 };
271
272 const struct file_operations lov_proc_target_fops = {
273         .owner   = THIS_MODULE,
274         .open    = lov_target_seq_open,
275         .read    = seq_read,
276         .llseek  = seq_lseek,
277         .release = lprocfs_seq_release,
278 };
279 #endif /* CONFIG_PROC_FS */
280
281 static struct attribute *lov_attrs[] = {
282         &lustre_attr_activeobd.attr,
283         &lustre_attr_numobd.attr,
284         &lustre_attr_desc_uuid.attr,
285         &lustre_attr_stripeoffset.attr,
286         &lustre_attr_stripetype.attr,
287         &lustre_attr_stripecount.attr,
288         NULL,
289 };
290
291 int lov_tunables_init(struct obd_device *obd)
292 {
293         struct lov_obd *lov = &obd->u.lov;
294 #if defined(CONFIG_PROC_FS) && defined(HAVE_SERVER_SUPPORT)
295         struct obd_type *type;
296 #endif
297         int rc;
298
299         obd->obd_vars = lprocfs_lov_obd_vars;
300 #if defined(CONFIG_PROC_FS) && defined(HAVE_SERVER_SUPPORT)
301         /* If this is true then both client (lov) and server
302          * (lod) are on the same node. The lod layer if loaded
303          * first will register the lov proc directory. In that
304          * case obd->obd_type->typ_procroot will be not set.
305          * Instead we use type->typ_procsym as the parent.
306          */
307         type = class_search_type(LUSTRE_LOD_NAME);
308         if (type && type->typ_procsym) {
309                 obd->obd_proc_entry = lprocfs_register(obd->obd_name,
310                                                        type->typ_procsym,
311                                                        obd->obd_vars, obd);
312                 if (IS_ERR(obd->obd_proc_entry)) {
313                         rc = PTR_ERR(obd->obd_proc_entry);
314                         CERROR("error %d setting up lprocfs for %s\n", rc,
315                                obd->obd_name);
316                         obd->obd_proc_entry = NULL;
317                 }
318         }
319 #endif
320         obd->obd_ktype.default_attrs = lov_attrs;
321         rc = lprocfs_obd_setup(obd, false);
322         if (rc)
323                 GOTO(out, rc);
324
325 #ifdef CONFIG_PROC_FS
326         rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd", 0444,
327                                 &lov_proc_target_fops, obd);
328         if (rc)
329                 CWARN("%s: Error adding the target_obd file : rc %d\n",
330                       obd->obd_name, rc);
331
332         lov->lov_pool_proc_entry = lprocfs_register("pools",
333                                                     obd->obd_proc_entry,
334                                                     NULL, NULL);
335         if (IS_ERR(lov->lov_pool_proc_entry)) {
336                 rc = PTR_ERR(lov->lov_pool_proc_entry);
337                 CERROR("%s: error setting up debugfs for pools : rc %d\n",
338                        obd->obd_name, rc);
339                 lov->lov_pool_proc_entry = NULL;
340         }
341 #endif /* CONFIG_FS_PROC */
342 out:
343         return rc;
344 }