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