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 struct interval_node_extent ext;
122 char start_nidstr[LNET_NIDSTR_SIZE];
123 char end_nidstr[LNET_NIDSTR_SIZE];
127 mutex_lock(&active_config_lock);
128 nodemap = nodemap_lookup(m->private);
129 if (IS_ERR(nodemap)) {
130 mutex_unlock(&active_config_lock);
131 rc = PTR_ERR(nodemap);
132 CERROR("cannot find nodemap '%s': rc = %d\n",
133 (char *)m->private, rc);
137 seq_printf(m, "[\n");
138 down_read(&active_config->nmc_range_tree_lock);
139 list_for_each_entry(range, &nodemap->nm_ranges, rn_list) {
141 seq_printf(m, ",\n");
143 ext = range->rn_node.in_extent;
144 libcfs_nid2str_r(ext.start, start_nidstr, sizeof(start_nidstr));
145 libcfs_nid2str_r(ext.end, end_nidstr, sizeof(end_nidstr));
146 seq_printf(m, " { id: %u, start_nid: %s, end_nid: %s }",
147 range->rn_id, start_nidstr, end_nidstr);
149 up_read(&active_config->nmc_range_tree_lock);
150 mutex_unlock(&active_config_lock);
152 seq_printf(m, "]\n");
154 nodemap_putref(nodemap);
159 * Connects nodemap_idmap_show to proc file.
161 * \param inode inode of seq file in proc fs
162 * \param file seq file
165 static int nodemap_ranges_open(struct inode *inode, struct file *file)
167 return single_open(file, nodemap_ranges_show, PDE_DATA(inode));
171 * Reads and prints the fileset for the given nodemap.
173 * \param m seq file in proc fs
177 static int nodemap_fileset_seq_show(struct seq_file *m, void *data)
179 struct lu_nodemap *nodemap;
182 mutex_lock(&active_config_lock);
183 nodemap = nodemap_lookup(m->private);
184 mutex_unlock(&active_config_lock);
185 if (IS_ERR(nodemap)) {
186 rc = PTR_ERR(nodemap);
187 CERROR("cannot find nodemap '%s': rc = %d\n",
188 (char *)m->private, rc);
192 seq_printf(m, "%s\n", nodemap->nm_fileset);
193 nodemap_putref(nodemap);
198 * Set a fileset on a nodemap.
200 * \param[in] file proc file
201 * \param[in] buffer string, "<fileset>"
202 * \param[in] count \a buffer length
203 * \param[in] off unused
204 * \retval \a count on success
205 * \retval negative number on error
208 nodemap_fileset_seq_write(struct file *file,
209 const char __user *buffer,
210 size_t count, loff_t *off)
212 struct seq_file *m = file->private_data;
220 if (count > PATH_MAX)
223 OBD_ALLOC(nm_fileset, count + 1);
224 /* OBD_ALLOC zero-fills the buffer */
225 if (nm_fileset == NULL)
228 if (copy_from_user(nm_fileset, buffer, count))
229 GOTO(out, rc = -EFAULT);
231 rc = nodemap_set_fileset(m->private, nm_fileset);
233 GOTO(out, rc = -EINVAL);
237 OBD_FREE(nm_fileset, count + 1);
241 LPROC_SEQ_FOPS(nodemap_fileset);
244 * Reads and prints the SELinux policy info for the given nodemap.
246 * \param m seq file in proc fs
250 static int nodemap_sepol_seq_show(struct seq_file *m, void *data)
252 struct lu_nodemap *nodemap;
255 mutex_lock(&active_config_lock);
256 nodemap = nodemap_lookup(m->private);
257 mutex_unlock(&active_config_lock);
258 if (IS_ERR(nodemap)) {
259 rc = PTR_ERR(nodemap);
260 CERROR("cannot find nodemap '%s': rc = %d\n",
261 (char *)m->private, rc);
265 seq_printf(m, "%s\n", nodemap_get_sepol(nodemap));
266 nodemap_putref(nodemap);
271 * Set SELinux policy info on a nodemap.
273 * \param[in] file proc file
274 * \param[in] buffer string, "<sepol>"
275 * \param[in] count \a buffer length
276 * \param[in] off unused
277 * \retval \a count on success
278 * \retval negative number on error
281 nodemap_sepol_seq_write(struct file *file,
282 const char __user *buffer,
283 size_t count, loff_t *off)
285 struct seq_file *m = file->private_data;
286 char sepol[LUSTRE_NODEMAP_SEPOL_LENGTH + 1];
289 BUILD_BUG_ON(sizeof(sepol) !=
290 sizeof(((struct lu_nodemap *)0)->nm_sepol));
293 if (count >= sizeof(sepol))
294 GOTO(out, rc = -ENAMETOOLONG);
296 if (copy_from_user(sepol, buffer, count))
297 GOTO(out, rc = -EFAULT);
301 rc = nodemap_set_sepol(m->private, sepol);
310 LPROC_SEQ_FOPS(nodemap_sepol);
313 * Reads and prints the exports attached to the given nodemap.
315 * \param m seq file in proc fs, stores nodemap
319 static int nodemap_exports_show(struct seq_file *m, void *data)
321 struct lu_nodemap *nodemap;
322 struct obd_export *exp;
323 char nidstr[LNET_NIDSTR_SIZE] = "<unknown>";
326 mutex_lock(&active_config_lock);
327 nodemap = nodemap_lookup(m->private);
328 mutex_unlock(&active_config_lock);
329 if (IS_ERR(nodemap)) {
330 rc = PTR_ERR(nodemap);
331 CERROR("cannot find nodemap '%s': rc = %d\n",
332 (char *)m->private, rc);
336 seq_printf(m, "[\n");
338 mutex_lock(&nodemap->nm_member_list_lock);
339 list_for_each_entry(exp, &nodemap->nm_member_list,
340 exp_target_data.ted_nodemap_member) {
341 if (exp->exp_connection != NULL)
342 libcfs_nid2str_r(exp->exp_connection->c_peer.nid,
343 nidstr, sizeof(nidstr));
345 seq_printf(m, " { nid: %s, uuid: %s },",
346 nidstr, exp->exp_client_uuid.uuid);
348 mutex_unlock(&nodemap->nm_member_list_lock);
351 seq_printf(m, "]\n");
353 nodemap_putref(nodemap);
358 * Attaches nodemap_idmap_show to proc file.
360 * \param inode inode of seq file in proc fs
361 * \param file seq file
364 static int nodemap_exports_open(struct inode *inode, struct file *file)
366 return single_open(file, nodemap_exports_show, PDE_DATA(inode));
370 * Reads and prints the active flag for the given nodemap.
372 * \param m seq file in proc fs
376 static int nodemap_active_seq_show(struct seq_file *m, void *data)
378 seq_printf(m, "%u\n", (unsigned int)nodemap_active);
383 * Activate/deactivate nodemap.
385 * \param[in] file proc file
386 * \param[in] buffer string, "1" or "0" to activate/deactivate nodemap
387 * \param[in] count \a buffer length
388 * \param[in] off unused
389 * \retval \a count on success
390 * \retval negative number on error
393 nodemap_active_seq_write(struct file *file, const char __user *buffer,
394 size_t count, loff_t *off)
396 char active_string[NODEMAP_LPROC_FLAG_LEN + 1];
397 long unsigned int active;
403 if (count >= sizeof(active_string))
406 if (copy_from_user(active_string, buffer, count))
409 active_string[count] = '\0';
410 rc = kstrtoul(active_string, 10, &active);
414 nodemap_activate(active);
418 LPROC_SEQ_FOPS(nodemap_active);
421 * Reads and prints the nodemap ID for the given nodemap.
423 * \param m seq file in proc fs
427 static int nodemap_id_seq_show(struct seq_file *m, void *data)
429 struct lu_nodemap *nodemap;
431 mutex_lock(&active_config_lock);
432 nodemap = nodemap_lookup(m->private);
433 mutex_unlock(&active_config_lock);
434 if (IS_ERR(nodemap)) {
435 int rc = PTR_ERR(nodemap);
436 CERROR("cannot find nodemap '%s': rc = %d\n",
437 (char *)m->private, rc);
441 seq_printf(m, "%u\n", nodemap->nm_id);
442 nodemap_putref(nodemap);
445 LPROC_SEQ_FOPS_RO(nodemap_id);
448 * Reads and prints the root squash UID for the given nodemap.
450 * \param m seq file in proc fs
454 static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data)
456 struct lu_nodemap *nodemap;
458 mutex_lock(&active_config_lock);
459 nodemap = nodemap_lookup(m->private);
460 mutex_unlock(&active_config_lock);
461 if (IS_ERR(nodemap)) {
462 int rc = PTR_ERR(nodemap);
463 CERROR("cannot find nodemap '%s': rc = %d\n",
464 (char *)m->private, rc);
468 seq_printf(m, "%u\n", nodemap->nm_squash_uid);
469 nodemap_putref(nodemap);
474 * Reads and prints the root squash GID for the given nodemap.
476 * \param m seq file in proc fs
480 static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data)
482 struct lu_nodemap *nodemap;
484 mutex_lock(&active_config_lock);
485 nodemap = nodemap_lookup(m->private);
486 mutex_unlock(&active_config_lock);
487 if (IS_ERR(nodemap)) {
488 int rc = PTR_ERR(nodemap);
489 CERROR("cannot find nodemap '%s': rc = %d\n",
490 (char *)m->private, rc);
494 seq_printf(m, "%u\n", nodemap->nm_squash_gid);
495 nodemap_putref(nodemap);
500 * Reads and prints the trusted flag for the given nodemap.
502 * \param m seq file in proc fs
506 static int nodemap_trusted_seq_show(struct seq_file *m, void *data)
508 struct lu_nodemap *nodemap;
510 mutex_lock(&active_config_lock);
511 nodemap = nodemap_lookup(m->private);
512 mutex_unlock(&active_config_lock);
513 if (IS_ERR(nodemap)) {
514 int rc = PTR_ERR(nodemap);
516 CERROR("cannot find nodemap '%s': rc = %d\n",
517 (char *)m->private, rc);
521 seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids);
522 nodemap_putref(nodemap);
527 * Reads and prints the admin flag for the given nodemap.
529 * \param m seq file in proc fs
533 static int nodemap_admin_seq_show(struct seq_file *m, void *data)
535 struct lu_nodemap *nodemap;
538 mutex_lock(&active_config_lock);
539 nodemap = nodemap_lookup(m->private);
540 mutex_unlock(&active_config_lock);
541 if (IS_ERR(nodemap)) {
542 rc = PTR_ERR(nodemap);
543 CERROR("cannot find nodemap '%s': rc = %d\n",
544 (char *)m->private, rc);
548 seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access);
549 nodemap_putref(nodemap);
554 * Reads and prints the mapping mode for the given nodemap.
556 * \param m seq file in proc fs
560 static int nodemap_map_mode_seq_show(struct seq_file *m, void *data)
562 struct lu_nodemap *nodemap;
565 mutex_lock(&active_config_lock);
566 nodemap = nodemap_lookup(m->private);
567 mutex_unlock(&active_config_lock);
568 if (IS_ERR(nodemap)) {
569 rc = PTR_ERR(nodemap);
570 CERROR("cannot find nodemap '%s': rc = %d\n",
571 (char *)m->private, rc);
575 if (nodemap->nmf_map_uid_only)
576 seq_printf(m, "uid_only\n");
577 else if (nodemap->nmf_map_gid_only)
578 seq_printf(m, "gid_only\n");
580 seq_printf(m, "both\n");
582 nodemap_putref(nodemap);
587 * Reads and prints the deny_unknown flag for the given nodemap.
589 * \param m seq file in proc fs
593 static int nodemap_deny_unknown_seq_show(struct seq_file *m, void *data)
595 struct lu_nodemap *nodemap;
598 mutex_lock(&active_config_lock);
599 nodemap = nodemap_lookup(m->private);
600 mutex_unlock(&active_config_lock);
601 if (IS_ERR(nodemap)) {
602 rc = PTR_ERR(nodemap);
603 CERROR("cannot find nodemap '%s': rc = %d\n",
604 (char *)m->private, rc);
608 seq_printf(m, "%d\n", (int)nodemap->nmf_deny_unknown);
609 nodemap_putref(nodemap);
614 * Reads and prints the audit_mode flag for the given nodemap.
616 * \param m seq file in proc fs
620 static int nodemap_audit_mode_seq_show(struct seq_file *m, void *data)
622 struct lu_nodemap *nodemap;
625 mutex_lock(&active_config_lock);
626 nodemap = nodemap_lookup(m->private);
627 mutex_unlock(&active_config_lock);
628 if (IS_ERR(nodemap)) {
629 rc = PTR_ERR(nodemap);
630 CERROR("cannot find nodemap '%s': rc = %d\n",
631 (char *)m->private, rc);
635 seq_printf(m, "%d\n", (int)nodemap->nmf_enable_audit);
636 nodemap_putref(nodemap);
641 * Reads and prints the forbid_encryption flag for the given nodemap.
643 * \param m seq file in proc fs
647 static int nodemap_forbid_encryption_seq_show(struct seq_file *m, void *data)
649 struct lu_nodemap *nodemap;
652 mutex_lock(&active_config_lock);
653 nodemap = nodemap_lookup(m->private);
654 mutex_unlock(&active_config_lock);
655 if (IS_ERR(nodemap)) {
656 rc = PTR_ERR(nodemap);
657 CERROR("cannot find nodemap '%s': rc = %d\n",
658 (char *)m->private, rc);
662 seq_printf(m, "%d\n", (int)nodemap->nmf_forbid_encryption);
663 nodemap_putref(nodemap);
667 static struct lprocfs_vars lprocfs_nm_module_vars[] = {
670 .fops = &nodemap_active_fops,
677 LPROC_SEQ_FOPS_RO(nodemap_trusted);
678 LPROC_SEQ_FOPS_RO(nodemap_admin);
679 LPROC_SEQ_FOPS_RO(nodemap_squash_uid);
680 LPROC_SEQ_FOPS_RO(nodemap_squash_gid);
682 LPROC_SEQ_FOPS_RO(nodemap_deny_unknown);
683 LPROC_SEQ_FOPS_RO(nodemap_map_mode);
684 LPROC_SEQ_FOPS_RO(nodemap_audit_mode);
685 LPROC_SEQ_FOPS_RO(nodemap_forbid_encryption);
687 const struct file_operations nodemap_ranges_fops = {
688 .open = nodemap_ranges_open,
691 .release = single_release
694 const struct file_operations nodemap_idmap_fops = {
695 .open = nodemap_idmap_open,
698 .release = single_release
701 const struct file_operations nodemap_exports_fops = {
702 .open = nodemap_exports_open,
705 .release = single_release
708 static struct lprocfs_vars lprocfs_nodemap_vars[] = {
711 .fops = &nodemap_id_fops,
714 .name = "trusted_nodemap",
715 .fops = &nodemap_trusted_fops,
718 .name = "admin_nodemap",
719 .fops = &nodemap_admin_fops,
722 .name = "deny_unknown",
723 .fops = &nodemap_deny_unknown_fops,
727 .fops = &nodemap_map_mode_fops,
730 .name = "audit_mode",
731 .fops = &nodemap_audit_mode_fops,
734 .name = "forbid_encryption",
735 .fops = &nodemap_forbid_encryption_fops,
738 .name = "squash_uid",
739 .fops = &nodemap_squash_uid_fops,
742 .name = "squash_gid",
743 .fops = &nodemap_squash_gid_fops,
747 .fops = &nodemap_ranges_fops,
751 .fops = &nodemap_fileset_fops,
755 .fops = &nodemap_sepol_fops,
759 .fops = &nodemap_exports_fops,
763 .fops = &nodemap_idmap_fops,
770 static struct lprocfs_vars lprocfs_default_nodemap_vars[] = {
773 .fops = &nodemap_id_fops,
776 .name = "trusted_nodemap",
777 .fops = &nodemap_trusted_fops,
780 .name = "admin_nodemap",
781 .fops = &nodemap_admin_fops,
784 .name = "deny_unknown",
785 .fops = &nodemap_deny_unknown_fops,
788 .name = "squash_uid",
789 .fops = &nodemap_squash_uid_fops,
792 .name = "squash_gid",
793 .fops = &nodemap_squash_gid_fops,
797 .fops = &nodemap_fileset_fops,
801 .fops = &nodemap_exports_fops,
804 .name = "audit_mode",
805 .fops = &nodemap_audit_mode_fops,
808 .name = "forbid_encryption",
809 .fops = &nodemap_forbid_encryption_fops,
817 * Initialize the nodemap procfs directory.
821 int nodemap_procfs_init(void)
825 proc_lustre_nodemap_root = lprocfs_register(LUSTRE_NODEMAP_NAME,
827 lprocfs_nm_module_vars,
829 if (IS_ERR(proc_lustre_nodemap_root)) {
830 rc = PTR_ERR(proc_lustre_nodemap_root);
831 CERROR("cannot create 'nodemap' directory: rc = %d\n",
833 proc_lustre_nodemap_root = NULL;
839 * Cleanup nodemap proc entry data structures.
841 void nodemap_procfs_exit(void)
843 struct nodemap_pde *nm_pde;
844 struct nodemap_pde *tmp;
846 lprocfs_remove(&proc_lustre_nodemap_root);
847 list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list,
849 list_del(&nm_pde->npe_list_member);
850 OBD_FREE_PTR(nm_pde);
855 * Remove a nodemap's procfs entry and related data.
857 void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde)
859 lprocfs_remove(&nm_pde->npe_proc_entry);
860 list_del(&nm_pde->npe_list_member);
861 OBD_FREE_PTR(nm_pde);
865 * Register the proc directory for a nodemap
867 * \param nodemap nodemap to make the proc dir for
868 * \param is_default: 1 if default nodemap
871 int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default)
873 struct nodemap_pde *nm_entry;
876 OBD_ALLOC_PTR(nm_entry);
877 if (nm_entry == NULL)
878 GOTO(out, rc = -ENOMEM);
880 nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name,
881 proc_lustre_nodemap_root);
882 if (IS_ERR(nm_entry->npe_proc_entry))
883 GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry));
885 snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s",
888 /* Use the nodemap name as stored on the PDE as the private data. This
889 * is so a nodemap struct can be replaced without updating the proc
892 rc = lprocfs_add_vars(nm_entry->npe_proc_entry,
893 (is_default ? lprocfs_default_nodemap_vars :
894 lprocfs_nodemap_vars),
897 lprocfs_remove(&nm_entry->npe_proc_entry);
899 list_add(&nm_entry->npe_list_member, &nodemap_pde_list);
903 CERROR("cannot create 'nodemap/%s': rc = %d\n",
904 nodemap->nm_name, rc);
905 if (nm_entry != NULL) {
906 OBD_FREE_PTR(nm_entry);
911 nodemap->nm_pde_data = nm_entry;