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