4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
23 * Copyright (C) 2013, Trustees of Indiana University
25 * Copyright (c) 2014, 2017, Intel Corporation.
27 * Author: Joshua Walgenbach <jjw@iu.edu>
30 #define NODEMAP_LPROC_ID_LEN 16
31 #define NODEMAP_LPROC_FLAG_LEN 2
33 #include <lprocfs_status.h>
34 #include <lustre_net.h>
35 #include <lustre_export.h>
36 #include <obd_class.h>
37 #include <interval_tree.h>
38 #include "nodemap_internal.h"
40 static LIST_HEAD(nodemap_pde_list);
43 * Reads and prints the idmap for the given nodemap.
45 * \param m seq file in proc fs
49 static int nodemap_idmap_show(struct seq_file *m, void *data)
51 struct lu_nodemap *nodemap;
52 struct lu_idmap *idmap;
57 mutex_lock(&active_config_lock);
58 nodemap = nodemap_lookup(m->private);
59 mutex_unlock(&active_config_lock);
60 if (IS_ERR(nodemap)) {
61 rc = PTR_ERR(nodemap);
62 CERROR("cannot find nodemap '%s': rc = %d\n",
63 (char *)m->private, rc);
68 down_read(&nodemap->nm_idmap_lock);
69 for (node = rb_first(&nodemap->nm_client_to_fs_uidmap); node;
70 node = rb_next(node)) {
74 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
76 seq_printf(m, " { idtype: uid, client_id: %u, "
77 "fs_id: %u }", idmap->id_client,
80 for (node = rb_first(&nodemap->nm_client_to_fs_gidmap);
81 node; node = rb_next(node)) {
84 idmap = rb_entry(node, struct lu_idmap, id_client_to_fs);
86 seq_printf(m, " { idtype: gid, client_id: %u, "
87 "fs_id: %u }", idmap->id_client,
90 up_read(&nodemap->nm_idmap_lock);
94 nodemap_putref(nodemap);
99 * Attaches nodemap_idmap_show to proc file.
101 * \param inode inode of seq file in proc fs
102 * \param file seq file
105 static int nodemap_idmap_open(struct inode *inode, struct file *file)
107 return single_open(file, nodemap_idmap_show, PDE_DATA(inode));
111 * Reads and prints the NID ranges for the given nodemap.
113 * \param m seq file in proc fs
117 static int nodemap_ranges_show(struct seq_file *m, void *data)
119 struct lu_nodemap *nodemap;
120 struct lu_nid_range *range;
121 char start_nidstr[LNET_NIDSTR_SIZE];
122 char end_nidstr[LNET_NIDSTR_SIZE];
126 mutex_lock(&active_config_lock);
127 nodemap = nodemap_lookup(m->private);
128 if (IS_ERR(nodemap)) {
129 mutex_unlock(&active_config_lock);
130 rc = PTR_ERR(nodemap);
131 CERROR("cannot find nodemap '%s': rc = %d\n",
132 (char *)m->private, rc);
136 seq_printf(m, "[\n");
137 down_read(&active_config->nmc_range_tree_lock);
138 list_for_each_entry(range, &nodemap->nm_ranges, rn_list) {
140 seq_printf(m, ",\n");
142 libcfs_nid2str_r(range->rn_start, start_nidstr, sizeof(start_nidstr));
143 libcfs_nid2str_r(range->rn_end, end_nidstr, sizeof(end_nidstr));
144 seq_printf(m, " { id: %u, start_nid: %s, end_nid: %s }",
145 range->rn_id, start_nidstr, end_nidstr);
147 up_read(&active_config->nmc_range_tree_lock);
148 mutex_unlock(&active_config_lock);
150 seq_printf(m, "]\n");
152 nodemap_putref(nodemap);
157 * Connects nodemap_idmap_show to proc file.
159 * \param inode inode of seq file in proc fs
160 * \param file seq file
163 static int nodemap_ranges_open(struct inode *inode, struct file *file)
165 return single_open(file, nodemap_ranges_show, PDE_DATA(inode));
169 * Reads and prints the fileset for the given nodemap.
171 * \param m seq file in proc fs
175 static int nodemap_fileset_seq_show(struct seq_file *m, void *data)
177 struct lu_nodemap *nodemap;
180 mutex_lock(&active_config_lock);
181 nodemap = nodemap_lookup(m->private);
182 mutex_unlock(&active_config_lock);
183 if (IS_ERR(nodemap)) {
184 rc = PTR_ERR(nodemap);
185 CERROR("cannot find nodemap '%s': rc = %d\n",
186 (char *)m->private, rc);
190 seq_printf(m, "%s\n", nodemap->nm_fileset);
191 nodemap_putref(nodemap);
196 * Set a fileset on a nodemap.
198 * \param[in] file proc file
199 * \param[in] buffer string, "<fileset>"
200 * \param[in] count \a buffer length
201 * \param[in] off unused
202 * \retval \a count on success
203 * \retval negative number on error
206 nodemap_fileset_seq_write(struct file *file,
207 const char __user *buffer,
208 size_t count, loff_t *off)
210 struct seq_file *m = file->private_data;
218 if (count > PATH_MAX)
221 OBD_ALLOC(nm_fileset, count + 1);
222 /* OBD_ALLOC zero-fills the buffer */
223 if (nm_fileset == NULL)
226 if (copy_from_user(nm_fileset, buffer, count))
227 GOTO(out, rc = -EFAULT);
229 rc = nodemap_set_fileset(m->private, nm_fileset);
231 GOTO(out, rc = -EINVAL);
235 OBD_FREE(nm_fileset, count + 1);
239 LPROC_SEQ_FOPS(nodemap_fileset);
242 * Reads and prints the SELinux policy info for the given nodemap.
244 * \param m seq file in proc fs
248 static int nodemap_sepol_seq_show(struct seq_file *m, void *data)
250 struct lu_nodemap *nodemap;
253 mutex_lock(&active_config_lock);
254 nodemap = nodemap_lookup(m->private);
255 mutex_unlock(&active_config_lock);
256 if (IS_ERR(nodemap)) {
257 rc = PTR_ERR(nodemap);
258 CERROR("cannot find nodemap '%s': rc = %d\n",
259 (char *)m->private, rc);
263 seq_printf(m, "%s\n", nodemap_get_sepol(nodemap));
264 nodemap_putref(nodemap);
269 * Set SELinux policy info on a nodemap.
271 * \param[in] file proc file
272 * \param[in] buffer string, "<sepol>"
273 * \param[in] count \a buffer length
274 * \param[in] off unused
275 * \retval \a count on success
276 * \retval negative number on error
279 nodemap_sepol_seq_write(struct file *file,
280 const char __user *buffer,
281 size_t count, loff_t *off)
283 struct seq_file *m = file->private_data;
284 char sepol[LUSTRE_NODEMAP_SEPOL_LENGTH + 1];
287 BUILD_BUG_ON(sizeof(sepol) !=
288 sizeof(((struct lu_nodemap *)0)->nm_sepol));
291 if (count >= sizeof(sepol))
292 GOTO(out, rc = -ENAMETOOLONG);
294 if (copy_from_user(sepol, buffer, count))
295 GOTO(out, rc = -EFAULT);
299 rc = nodemap_set_sepol(m->private, sepol);
308 LPROC_SEQ_FOPS(nodemap_sepol);
311 * Reads and prints the exports attached to the given nodemap.
313 * \param m seq file in proc fs, stores nodemap
317 static int nodemap_exports_show(struct seq_file *m, void *data)
319 struct lu_nodemap *nodemap;
320 struct obd_export *exp;
321 char nidstr[LNET_NIDSTR_SIZE] = "<unknown>";
324 mutex_lock(&active_config_lock);
325 nodemap = nodemap_lookup(m->private);
326 mutex_unlock(&active_config_lock);
327 if (IS_ERR(nodemap)) {
328 rc = PTR_ERR(nodemap);
329 CERROR("cannot find nodemap '%s': rc = %d\n",
330 (char *)m->private, rc);
334 seq_printf(m, "[\n");
336 mutex_lock(&nodemap->nm_member_list_lock);
337 list_for_each_entry(exp, &nodemap->nm_member_list,
338 exp_target_data.ted_nodemap_member) {
339 if (exp->exp_connection != NULL)
340 libcfs_nid2str_r(exp->exp_connection->c_peer.nid,
341 nidstr, sizeof(nidstr));
343 seq_printf(m, " { nid: %s, uuid: %s },",
344 nidstr, exp->exp_client_uuid.uuid);
346 mutex_unlock(&nodemap->nm_member_list_lock);
349 seq_printf(m, "]\n");
351 nodemap_putref(nodemap);
356 * Attaches nodemap_idmap_show to proc file.
358 * \param inode inode of seq file in proc fs
359 * \param file seq file
362 static int nodemap_exports_open(struct inode *inode, struct file *file)
364 return single_open(file, nodemap_exports_show, PDE_DATA(inode));
368 * Reads and prints the active flag for the given nodemap.
370 * \param m seq file in proc fs
374 static int nodemap_active_seq_show(struct seq_file *m, void *data)
376 seq_printf(m, "%u\n", (unsigned int)nodemap_active);
381 * Activate/deactivate nodemap.
383 * \param[in] file proc file
384 * \param[in] buffer string, "1" or "0" to activate/deactivate nodemap
385 * \param[in] count \a buffer length
386 * \param[in] off unused
387 * \retval \a count on success
388 * \retval negative number on error
391 nodemap_active_seq_write(struct file *file, const char __user *buffer,
392 size_t count, loff_t *off)
394 char active_string[NODEMAP_LPROC_FLAG_LEN + 1];
395 long unsigned int active;
401 if (count >= sizeof(active_string))
404 if (copy_from_user(active_string, buffer, count))
407 active_string[count] = '\0';
408 rc = kstrtoul(active_string, 10, &active);
412 nodemap_activate(active);
416 LPROC_SEQ_FOPS(nodemap_active);
419 * Reads and prints the nodemap ID for the given nodemap.
421 * \param m seq file in proc fs
425 static int nodemap_id_seq_show(struct seq_file *m, void *data)
427 struct lu_nodemap *nodemap;
429 mutex_lock(&active_config_lock);
430 nodemap = nodemap_lookup(m->private);
431 mutex_unlock(&active_config_lock);
432 if (IS_ERR(nodemap)) {
433 int rc = PTR_ERR(nodemap);
434 CERROR("cannot find nodemap '%s': rc = %d\n",
435 (char *)m->private, rc);
439 seq_printf(m, "%u\n", nodemap->nm_id);
440 nodemap_putref(nodemap);
443 LPROC_SEQ_FOPS_RO(nodemap_id);
446 * Reads and prints the root squash UID for the given nodemap.
448 * \param m seq file in proc fs
452 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
454 struct lu_nodemap *nodemap;
456 mutex_lock(&active_config_lock);
457 nodemap = nodemap_lookup(m->private);
458 mutex_unlock(&active_config_lock);
459 if (IS_ERR(nodemap)) {
460 int rc = PTR_ERR(nodemap);
461 CERROR("cannot find nodemap '%s': rc = %d\n",
462 (char *)m->private, rc);
466 seq_printf(m, "%u\n", nodemap->nm_squash_uid);
467 nodemap_putref(nodemap);
472 * Reads and prints the root squash GID for the given nodemap.
474 * \param m seq file in proc fs
478 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
480 struct lu_nodemap *nodemap;
482 mutex_lock(&active_config_lock);
483 nodemap = nodemap_lookup(m->private);
484 mutex_unlock(&active_config_lock);
485 if (IS_ERR(nodemap)) {
486 int rc = PTR_ERR(nodemap);
487 CERROR("cannot find nodemap '%s': rc = %d\n",
488 (char *)m->private, rc);
492 seq_printf(m, "%u\n", nodemap->nm_squash_gid);
493 nodemap_putref(nodemap);
498 * Reads and prints the trusted flag for the given nodemap.
500 * \param m seq file in proc fs
504 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
506 struct lu_nodemap *nodemap;
508 mutex_lock(&active_config_lock);
509 nodemap = nodemap_lookup(m->private);
510 mutex_unlock(&active_config_lock);
511 if (IS_ERR(nodemap)) {
512 int rc = PTR_ERR(nodemap);
514 CERROR("cannot find nodemap '%s': rc = %d\n",
515 (char *)m->private, rc);
519 seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
520 nodemap_putref(nodemap);
525 * Reads and prints the admin flag for the given nodemap.
527 * \param m seq file in proc fs
531 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
533 struct lu_nodemap *nodemap;
536 mutex_lock(&active_config_lock);
537 nodemap = nodemap_lookup(m->private);
538 mutex_unlock(&active_config_lock);
539 if (IS_ERR(nodemap)) {
540 rc = PTR_ERR(nodemap);
541 CERROR("cannot find nodemap '%s': rc = %d\n",
542 (char *)m->private, rc);
546 seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
547 nodemap_putref(nodemap);
552 * Reads and prints the mapping mode for the given nodemap.
554 * \param m seq file in proc fs
558 static int nodemap_map_mode_seq_show(struct seq_file *m, void *data)
560 struct lu_nodemap *nodemap;
563 mutex_lock(&active_config_lock);
564 nodemap = nodemap_lookup(m->private);
565 mutex_unlock(&active_config_lock);
566 if (IS_ERR(nodemap)) {
567 rc = PTR_ERR(nodemap);
568 CERROR("cannot find nodemap '%s': rc = %d\n",
569 (char *)m->private, rc);
573 if (nodemap->nmf_map_uid_only)
574 seq_printf(m, "uid_only\n");
575 else if (nodemap->nmf_map_gid_only)
576 seq_printf(m, "gid_only\n");
578 seq_printf(m, "both\n");
580 nodemap_putref(nodemap);
585 * Reads and prints the deny_unknown flag for the given nodemap.
587 * \param m seq file in proc fs
591 static int nodemap_deny_unknown_seq_show(struct seq_file *m, void *data)
593 struct lu_nodemap *nodemap;
596 mutex_lock(&active_config_lock);
597 nodemap = nodemap_lookup(m->private);
598 mutex_unlock(&active_config_lock);
599 if (IS_ERR(nodemap)) {
600 rc = PTR_ERR(nodemap);
601 CERROR("cannot find nodemap '%s': rc = %d\n",
602 (char *)m->private, rc);
606 seq_printf(m, "%d\n", (int)nodemap->nmf_deny_unknown);
607 nodemap_putref(nodemap);
612 * Reads and prints the audit_mode flag for the given nodemap.
614 * \param m seq file in proc fs
618 static int nodemap_audit_mode_seq_show(struct seq_file *m, void *data)
620 struct lu_nodemap *nodemap;
623 mutex_lock(&active_config_lock);
624 nodemap = nodemap_lookup(m->private);
625 mutex_unlock(&active_config_lock);
626 if (IS_ERR(nodemap)) {
627 rc = PTR_ERR(nodemap);
628 CERROR("cannot find nodemap '%s': rc = %d\n",
629 (char *)m->private, rc);
633 seq_printf(m, "%d\n", (int)nodemap->nmf_enable_audit);
634 nodemap_putref(nodemap);
639 * Reads and prints the forbid_encryption flag for the given nodemap.
641 * \param m seq file in proc fs
645 static int nodemap_forbid_encryption_seq_show(struct seq_file *m, void *data)
647 struct lu_nodemap *nodemap;
650 mutex_lock(&active_config_lock);
651 nodemap = nodemap_lookup(m->private);
652 mutex_unlock(&active_config_lock);
653 if (IS_ERR(nodemap)) {
654 rc = PTR_ERR(nodemap);
655 CERROR("cannot find nodemap '%s': rc = %d\n",
656 (char *)m->private, rc);
660 seq_printf(m, "%d\n", (int)nodemap->nmf_forbid_encryption);
661 nodemap_putref(nodemap);
665 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
668 .fops = &nodemap_active_fops,
675 LPROC_SEQ_FOPS_RO(nodemap_trusted);
676 LPROC_SEQ_FOPS_RO(nodemap_admin);
677 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
678 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
680 LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
681 LPROC_SEQ_FOPS_RO(nodemap_map_mode);
682 LPROC_SEQ_FOPS_RO(nodemap_audit_mode);
683 LPROC_SEQ_FOPS_RO(nodemap_forbid_encryption);
685 static const struct file_operations nodemap_ranges_fops = {
686 .open = nodemap_ranges_open,
689 .release = single_release
692 static const struct file_operations nodemap_idmap_fops = {
693 .open = nodemap_idmap_open,
696 .release = single_release
699 static const struct file_operations nodemap_exports_fops = {
700 .open = nodemap_exports_open,
703 .release = single_release
706 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
709 .fops = &nodemap_id_fops,
712 .name = "trusted_nodemap",
713 .fops = &nodemap_trusted_fops,
716 .name = "admin_nodemap",
717 .fops = &nodemap_admin_fops,
720 .name = "deny_unknown",
721 .fops = &nodemap_deny_unknown_fops,
725 .fops = &nodemap_map_mode_fops,
728 .name = "audit_mode",
729 .fops = &nodemap_audit_mode_fops,
732 .name = "forbid_encryption",
733 .fops = &nodemap_forbid_encryption_fops,
736 .name = "squash_uid",
737 .fops = &nodemap_squash_uid_fops,
740 .name = "squash_gid",
741 .fops = &nodemap_squash_gid_fops,
745 .fops = &nodemap_ranges_fops,
749 .fops = &nodemap_fileset_fops,
753 .fops = &nodemap_sepol_fops,
757 .fops = &nodemap_exports_fops,
761 .fops = &nodemap_idmap_fops,
768 static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
771 .fops = &nodemap_id_fops,
774 .name = "trusted_nodemap",
775 .fops = &nodemap_trusted_fops,
778 .name = "admin_nodemap",
779 .fops = &nodemap_admin_fops,
782 .name = "deny_unknown",
783 .fops = &nodemap_deny_unknown_fops,
786 .name = "squash_uid",
787 .fops = &nodemap_squash_uid_fops,
790 .name = "squash_gid",
791 .fops = &nodemap_squash_gid_fops,
795 .fops = &nodemap_fileset_fops,
799 .fops = &nodemap_exports_fops,
802 .name = "audit_mode",
803 .fops = &nodemap_audit_mode_fops,
806 .name = "forbid_encryption",
807 .fops = &nodemap_forbid_encryption_fops,
815 * Initialize the nodemap procfs directory.
819 int nodemap_procfs_init(void)
823 proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
825 lprocfs_nm_module_vars,
827 if (IS_ERR(proc_lustre_nodemap_root)) {
828 rc = PTR_ERR(proc_lustre_nodemap_root);
829 CERROR("cannot create 'nodemap' directory: rc = %d\n",
831 proc_lustre_nodemap_root = NULL;
837 * Cleanup nodemap proc entry data structures.
839 void nodemap_procfs_exit(void)
841 struct nodemap_pde *nm_pde;
842 struct nodemap_pde *tmp;
844 lprocfs_remove(&proc_lustre_nodemap_root);
845 list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list,
847 list_del(&nm_pde->npe_list_member);
848 OBD_FREE_PTR(nm_pde);
853 * Remove a nodemap's procfs entry and related data.
855 void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde)
857 lprocfs_remove(&nm_pde->npe_proc_entry);
858 list_del(&nm_pde->npe_list_member);
859 OBD_FREE_PTR(nm_pde);
863 * Register the proc directory for a nodemap
865 * \param nodemap nodemap to make the proc dir for
866 * \param is_default: 1 if default nodemap
869 int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default)
871 struct nodemap_pde *nm_entry;
874 OBD_ALLOC_PTR(nm_entry);
875 if (nm_entry == NULL)
876 GOTO(out, rc = -ENOMEM);
878 nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name,
879 proc_lustre_nodemap_root);
880 if (IS_ERR(nm_entry->npe_proc_entry))
881 GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry));
883 snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s",
886 /* Use the nodemap name as stored on the PDE as the private data. This
887 * is so a nodemap struct can be replaced without updating the proc
890 rc = lprocfs_add_vars(nm_entry->npe_proc_entry,
891 (is_default ? lprocfs_default_nodemap_vars :
892 lprocfs_nodemap_vars),
895 lprocfs_remove(&nm_entry->npe_proc_entry);
897 list_add(&nm_entry->npe_list_member, &nodemap_pde_list);
901 CERROR("cannot create 'nodemap/%s': rc = %d\n",
902 nodemap->nm_name, rc);
903 if (nm_entry != NULL) {
904 OBD_FREE_PTR(nm_entry);
909 nodemap->nm_pde_data = nm_entry;