Whamcloud - gitweb
LU-5435 lnet: lustre network latency simulation
[fs/lustre-release.git] / lustre / nodemap / nodemap_lproc.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) 2013, Trustees of Indiana University
24  * Author: Joshua Walgenbach <jjw@iu.edu>
25  */
26
27 #define NODEMAP_LPROC_ID_LEN 16
28 #define NODEMAP_LPROC_FLAG_LEN 2
29
30 #include <lprocfs_status.h>
31 #include <lustre_net.h>
32 #include <interval_tree.h>
33 #include "nodemap_internal.h"
34
35 static int nodemap_idmap_show(struct seq_file *m, void *data)
36 {
37         struct lu_nodemap       *nodemap = m->private;
38         struct lu_idmap         *idmap;
39         struct rb_node          *node;
40         bool                    cont = 0;
41
42         seq_printf(m, "[\n");
43         for (node = rb_first(&nodemap->nm_client_to_fs_uidmap); node;
44                                 node = rb_next(node)) {
45                 if (cont)
46                         seq_printf(m, ",\n");
47                 cont = 1;
48                 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
49                 if (idmap != NULL)
50                         seq_printf(m, " { idtype: uid, client_id: %u, "
51                                    "fs_id: %u }", idmap->id_client,
52                                    idmap->id_fs);
53         }
54         for (node = rb_first(&nodemap->nm_client_to_fs_gidmap);
55                                 node; node = rb_next(node)) {
56                 if (cont)
57                         seq_printf(m, ",\n");
58                 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
59                 if (idmap != NULL)
60                         seq_printf(m, " { idtype: gid, client_id: %u, "
61                                    "fs_id: %u }", idmap->id_client,
62                                    idmap->id_fs);
63         }
64         seq_printf(m, "\n");
65         seq_printf(m, "]\n");
66
67         return 0;
68 }
69
70 static int nodemap_idmap_open(struct inode *inode, struct file *file)
71 {
72         struct lu_nodemap *nodemap = PDE_DATA(inode);
73
74         return single_open(file, nodemap_idmap_show, nodemap);
75 }
76
77 static int nodemap_ranges_show(struct seq_file *m, void *data)
78 {
79         struct lu_nodemap               *nodemap = m->private;
80         struct lu_nid_range             *range;
81         struct interval_node_extent     ext;
82         bool                            cont = 0;
83
84         seq_printf(m, "[\n");
85         list_for_each_entry(range, &nodemap->nm_ranges, rn_list) {
86                 if (cont)
87                         seq_printf(m, ",\n");
88                 cont = 1;
89                 ext = range->rn_node.in_extent;
90                 seq_printf(m, " { id: %u, start_nid: %s, "
91                                 "end_nid: %s }",
92                            range->rn_id, libcfs_nid2str(ext.start),
93                            libcfs_nid2str(ext.end));
94         }
95         seq_printf(m, "\n");
96         seq_printf(m, "]\n");
97
98         return 0;
99 }
100
101 static int nodemap_ranges_open(struct inode *inode, struct file *file)
102 {
103         struct lu_nodemap *nodemap = PDE_DATA(inode);
104
105         return single_open(file, nodemap_ranges_show, nodemap);
106 }
107
108 static int nodemap_active_seq_show(struct seq_file *m, void *data)
109 {
110         return seq_printf(m, "%u\n", (unsigned int)nodemap_active);
111 }
112
113 static ssize_t
114 nodemap_active_seq_write(struct file *file, const char __user *buffer,
115                          size_t count, loff_t *off)
116 {
117         char    active_string[NODEMAP_LPROC_FLAG_LEN + 1];
118         __u32   active;
119         int     rc = count;
120
121         if (count == 0)
122                 return 0;
123
124         if (count > NODEMAP_LPROC_FLAG_LEN)
125                 return -EINVAL;
126
127         if (copy_from_user(active_string, buffer, count))
128                 return -EFAULT;
129
130         active_string[count] = '\0';
131         active = simple_strtoul(active_string, NULL, 10);
132         nodemap_active = active;
133
134         return rc;
135 }
136 LPROC_SEQ_FOPS(nodemap_active);
137
138 static int nodemap_id_seq_show(struct seq_file *m, void *data)
139 {
140         struct lu_nodemap *nodemap = m->private;
141
142         return seq_printf(m, "%u\n", nodemap->nm_id);
143 }
144 LPROC_SEQ_FOPS_RO(nodemap_id);
145
146 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
147 {
148         struct lu_nodemap *nodemap = m->private;
149
150         return seq_printf(m, "%u\n", nodemap->nm_squash_uid);
151 }
152
153 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
154 {
155         struct lu_nodemap *nodemap = m->private;
156
157         return seq_printf(m, "%u\n", nodemap->nm_squash_gid);
158 }
159
160 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
161 {
162         struct lu_nodemap *nodemap = m->private;
163
164         return seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
165 }
166
167 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
168 {
169         struct lu_nodemap *nodemap = m->private;
170
171         return seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
172 }
173
174 #ifdef NODEMAP_PROC_DEBUG
175 static int nodemap_proc_read_flag(const char __user *buffer,
176                                   unsigned long count, unsigned int *flag_p)
177 {
178         char scratch[NODEMAP_LPROC_FLAG_LEN + 1];
179
180         if (count == 0)
181                 return 0;
182
183         if (count > NODEMAP_LPROC_FLAG_LEN)
184                 return -EINVAL;
185
186         if (copy_from_user(scratch, buffer, count))
187                 return -EFAULT;
188
189         scratch[count] = '\0';
190         *flag_p = simple_strtoul(scratch, NULL, 10);
191
192         return 0;
193 }
194
195 static ssize_t
196 nodemap_squash_uid_seq_write(struct file *file, const char __user *buffer,
197                              size_t count, loff_t *off)
198 {
199         char                    squash[NODEMAP_LPROC_ID_LEN + 1];
200         struct seq_file         *m = file->private_data;
201         struct lu_nodemap       *nodemap = m->private;
202         uid_t                   squash_uid;
203         int                     rc = count;
204
205         if (count == 0)
206                 return 0;
207
208         if (count > NODEMAP_LPROC_FLAG_LEN)
209                 return -EINVAL;
210
211         if (copy_from_user(squash, buffer, count))
212                 return -EFAULT;
213
214         squash[count] = '\0';
215         squash_uid = simple_strtoul(squash, NULL, 10);
216         nodemap->nm_squash_uid = squash_uid;
217
218         return rc;
219 }
220
221 static ssize_t
222 nodemap_squash_gid_seq_write(struct file *file, const char __user *buffer,
223                              size_t count, loff_t *off)
224 {
225         char                    squash[NODEMAP_LPROC_ID_LEN + 1];
226         struct seq_file         *m = file->private_data;
227         struct lu_nodemap       *nodemap = m->private;
228         gid_t                   squash_gid;
229         int                     rc = count;
230
231         if (count == 0)
232                 return 0;
233
234         if (count > NODEMAP_LPROC_FLAG_LEN)
235                 return -EINVAL;
236
237         if (copy_from_user(squash, buffer, count))
238                 return -EFAULT;
239
240         squash[count] = '\0';
241         squash_gid = simple_strtoul(squash, NULL, 10);
242         nodemap->nm_squash_gid = squash_gid;
243
244         return rc;
245 }
246
247 static ssize_t
248 nodemap_trusted_seq_write(struct file *file, const char __user *buffer,
249                           size_t count, loff_t *off)
250 {
251         struct seq_file         *m = file->private_data;
252         struct lu_nodemap       *nodemap = m->private;
253         int                     flags;
254         int                     rc;
255
256         rc = nodemap_proc_read_flag(buffer, count, &flags);
257         if (rc == 0)
258                 nodemap->nmf_trust_client_ids = !!flags;
259
260         return rc;
261 }
262
263 static ssize_t
264 nodemap_admin_seq_write(struct file *file, const char __user *buffer,
265                         size_t count, loff_t *off)
266 {
267         struct seq_file         *m = file->private_data;
268         struct lu_nodemap       *nodemap = m->private;
269         int                     flags;
270         int                     rc;
271
272         rc = nodemap_proc_read_flag(buffer, count, &flags);
273         if (rc == 0)
274                 nodemap->nmf_allow_root_access = !!flags;
275
276         return rc;
277 }
278
279 static ssize_t
280 lprocfs_add_nodemap_seq_write(struct file *file, const char __user *buffer,
281                               size_t count, loff_t *off)
282 {
283         char    buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
284         char    *cpybuf = NULL;
285         char    *name;
286         char    *pos;
287         int     rc = count;
288
289         if (count == 0)
290                 return 0;
291
292         if (count > LUSTRE_NODEMAP_NAME_LENGTH)
293                 return -EINVAL;
294
295         if (copy_from_user(buf, buffer, count))
296                 return -EFAULT;
297
298         buf[count] = '\0';
299         pos = strchr(buf, '\n');
300         if (pos != NULL)
301                 *pos = '\0';
302
303         cpybuf = buf;
304         name = strsep(&cpybuf, " ");
305         if (name == NULL)
306                 return -EINVAL;
307
308         rc = nodemap_add(name);
309         if (rc == 0)
310                 rc = count;
311
312         return rc;
313 }
314 LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap);
315
316 static ssize_t
317 lprocfs_del_nodemap_seq_write(struct file *file, const char __user *buffer,
318                               size_t count, loff_t *off)
319 {
320         char    buf[LUSTRE_NODEMAP_NAME_LENGTH + 1];
321         char    *cpybuf = NULL;
322         char    *name;
323         char    *pos;
324         int     rc = count;
325
326         if (count == 0)
327                 return 0;
328
329         if (count > LUSTRE_NODEMAP_NAME_LENGTH)
330                 return -EINVAL;
331
332         if (copy_from_user(buf, buffer, count))
333                 return -EFAULT;
334
335         buf[count] = '\0';
336         pos = strchr(buf, '\n');
337         if (pos != NULL)
338                 *pos = '\0';
339
340         cpybuf = buf;
341         name = strsep(&cpybuf, " ");
342         if (name == NULL)
343                 return -EINVAL;
344
345         rc = nodemap_del(name);
346         if (rc == 0)
347                 rc = count;
348
349         return rc;
350
351 }
352 LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap);
353
354 #endif /* NODEMAP_PROC_DEBUG */
355
356 static struct lprocfs_seq_vars lprocfs_nodemap_module_vars[] = {
357         {
358                 .name           = "active",
359                 .fops           = &nodemap_active_fops,
360         },
361 #ifdef NODEMAP_PROC_DEBUG
362         {
363                 .name           = "add_nodemap",
364                 .fops           = &nodemap_add_nodemap_fops,
365         },
366         {
367                 .name           = "remove_nodemap",
368                 .fops           = &nodemap_del_nodemap_fops,
369         },
370 #endif /* NODEMAP_PROC_DEBUG */
371         {
372                 NULL
373         }
374 };
375
376 #ifdef NODEMAP_PROC_DEBUG
377 LPROC_SEQ_FOPS(nodemap_trusted);
378 LPROC_SEQ_FOPS(nodemap_admin);
379 LPROC_SEQ_FOPS(nodemap_squash_uid);
380 LPROC_SEQ_FOPS(nodemap_squash_gid);
381 #else
382 LPROC_SEQ_FOPS_RO(nodemap_trusted);
383 LPROC_SEQ_FOPS_RO(nodemap_admin);
384 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
385 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
386 #endif
387
388 const struct file_operations nodemap_ranges_fops = {
389         .open                   = nodemap_ranges_open,
390         .read                   = seq_read,
391         .llseek                 = seq_lseek,
392         .release                = single_release
393 };
394
395 const struct file_operations nodemap_idmap_fops = {
396         .open                   = nodemap_idmap_open,
397         .read                   = seq_read,
398         .llseek                 = seq_lseek,
399         .release                = single_release
400 };
401
402 static struct lprocfs_seq_vars lprocfs_nodemap_vars[] = {
403         {
404                 .name           = "id",
405                 .fops           = &nodemap_id_fops,
406         },
407         {
408                 .name           = "trusted_nodemap",
409                 .fops           = &nodemap_trusted_fops,
410         },
411         {
412                 .name           = "admin_nodemap",
413                 .fops           = &nodemap_admin_fops,
414         },
415         {
416                 .name           = "squash_uid",
417                 .fops           = &nodemap_squash_uid_fops,
418         },
419         {
420                 .name           = "squash_gid",
421                 .fops           = &nodemap_squash_gid_fops,
422         },
423         {
424                 .name           = "ranges",
425                 .fops           = &nodemap_ranges_fops,
426         },
427         {
428                 .name           = "idmap",
429                 .fops           = &nodemap_idmap_fops,
430         },
431         {
432                 NULL
433         }
434 };
435
436 static struct lprocfs_seq_vars lprocfs_default_nodemap_vars[] = {
437         {
438                 .name           = "id",
439                 .fops           = &nodemap_id_fops,
440         },
441         {
442                 .name           = "trusted_nodemap",
443                 .fops           = &nodemap_trusted_fops,
444         },
445         {
446                 .name           = "admin_nodemap",
447                 .fops           = &nodemap_admin_fops,
448         },
449         {
450                 .name           = "squash_uid",
451                 .fops           = &nodemap_squash_uid_fops,
452         },
453         {
454                 .name           = "squash_gid",
455                 .fops           = &nodemap_squash_gid_fops,
456         },
457         {
458                 NULL
459         }
460 };
461
462 int nodemap_procfs_init(void)
463 {
464         int rc = 0;
465
466         proc_lustre_nodemap_root = lprocfs_seq_register(LUSTRE_NODEMAP_NAME,
467                                                         proc_lustre_root,
468                                                         lprocfs_nodemap_module_vars,
469                                                         NULL);
470
471         if (IS_ERR(proc_lustre_nodemap_root)) {
472                 rc = PTR_ERR(proc_lustre_nodemap_root);
473                 CERROR("cannot create 'nodemap' directory: rc = %d\n",
474                        rc);
475                 proc_lustre_nodemap_root = NULL;
476         }
477
478         return rc;
479 }
480
481 /**
482  * Register the proc directory for a nodemap
483  *
484  * \param       name            name of nodemap
485  * \param       is_default:     1 if default nodemap
486  * \retval      0               success
487  */
488 int lprocfs_nodemap_register(const char *name,
489                              bool is_default,
490                              struct lu_nodemap *nodemap)
491 {
492         struct proc_dir_entry   *nodemap_proc_entry;
493         int                     rc = 0;
494
495         if (is_default)
496                 nodemap_proc_entry =
497                         lprocfs_seq_register(name,
498                                          proc_lustre_nodemap_root,
499                                          lprocfs_default_nodemap_vars,
500                                          nodemap);
501         else
502                 nodemap_proc_entry = lprocfs_seq_register(name,
503                                                           proc_lustre_nodemap_root,
504                                                           lprocfs_nodemap_vars,
505                                                           nodemap);
506
507         if (IS_ERR(nodemap_proc_entry)) {
508                 rc = PTR_ERR(nodemap_proc_entry);
509                 CERROR("cannot create 'nodemap/%s': rc = %d\n", name, rc);
510                 nodemap_proc_entry = NULL;
511         }
512
513         nodemap->nm_proc_entry = nodemap_proc_entry;
514
515         return rc;
516 }