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