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