X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fptlrpc%2Fnodemap_lproc.c;h=253952281de31cac9870d620b2bc685b42aadbb8;hp=6da0fd37bc841d3e82d62ba1a38e83a4ee5b8407;hb=f55fdfff5dede69e6674999fb02c1add513704f0;hpb=7a32eff39c8b4bd17f173a62293374c5b4ff04e1 diff --git a/lustre/ptlrpc/nodemap_lproc.c b/lustre/ptlrpc/nodemap_lproc.c index 6da0fd3..2539522 100644 --- a/lustre/ptlrpc/nodemap_lproc.c +++ b/lustre/ptlrpc/nodemap_lproc.c @@ -22,7 +22,7 @@ /* * Copyright (C) 2013, Trustees of Indiana University * - * Copyright (c) 2014, 2015, Intel Corporation. + * Copyright (c) 2014, 2017, Intel Corporation. * * Author: Joshua Walgenbach */ @@ -65,7 +65,7 @@ static int nodemap_idmap_show(struct seq_file *m, void *data) } seq_printf(m, "[\n"); - read_lock(&nodemap->nm_idmap_lock); + down_read(&nodemap->nm_idmap_lock); for (node = rb_first(&nodemap->nm_client_to_fs_uidmap); node; node = rb_next(node)) { if (cont) @@ -87,7 +87,7 @@ static int nodemap_idmap_show(struct seq_file *m, void *data) "fs_id: %u }", idmap->id_client, idmap->id_fs); } - read_unlock(&nodemap->nm_idmap_lock); + up_read(&nodemap->nm_idmap_lock); seq_printf(m, "\n"); seq_printf(m, "]\n"); @@ -118,7 +118,6 @@ static int nodemap_ranges_show(struct seq_file *m, void *data) { struct lu_nodemap *nodemap; struct lu_nid_range *range; - struct interval_node_extent ext; char start_nidstr[LNET_NIDSTR_SIZE]; char end_nidstr[LNET_NIDSTR_SIZE]; bool cont = false; @@ -140,9 +139,8 @@ static int nodemap_ranges_show(struct seq_file *m, void *data) if (cont) seq_printf(m, ",\n"); cont = 1; - ext = range->rn_node.in_extent; - libcfs_nid2str_r(ext.start, start_nidstr, sizeof(start_nidstr)); - libcfs_nid2str_r(ext.end, end_nidstr, sizeof(end_nidstr)); + libcfs_nid2str_r(range->rn_start, start_nidstr, sizeof(start_nidstr)); + libcfs_nid2str_r(range->rn_end, end_nidstr, sizeof(end_nidstr)); seq_printf(m, " { id: %u, start_nid: %s, end_nid: %s }", range->rn_id, start_nidstr, end_nidstr); } @@ -241,6 +239,75 @@ out: LPROC_SEQ_FOPS(nodemap_fileset); /** + * Reads and prints the SELinux policy info for the given nodemap. + * + * \param m seq file in proc fs + * \param data unused + * \retval 0 success + */ +static int nodemap_sepol_seq_show(struct seq_file *m, void *data) +{ + struct lu_nodemap *nodemap; + int rc = 0; + + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) { + rc = PTR_ERR(nodemap); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); + return rc; + } + + seq_printf(m, "%s\n", nodemap_get_sepol(nodemap)); + nodemap_putref(nodemap); + return rc; +} + +/** + * Set SELinux policy info on a nodemap. + * + * \param[in] file proc file + * \param[in] buffer string, "" + * \param[in] count \a buffer length + * \param[in] off unused + * \retval \a count on success + * \retval negative number on error + */ +static ssize_t +nodemap_sepol_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) +{ + struct seq_file *m = file->private_data; + char sepol[LUSTRE_NODEMAP_SEPOL_LENGTH + 1]; + int rc = 0; + + BUILD_BUG_ON(sizeof(sepol) != + sizeof(((struct lu_nodemap *)0)->nm_sepol)); + + if (count > 0) { + if (count >= sizeof(sepol)) + GOTO(out, rc = -ENAMETOOLONG); + + if (copy_from_user(sepol, buffer, count)) + GOTO(out, rc = -EFAULT); + + sepol[count] = '\0'; + + rc = nodemap_set_sepol(m->private, sepol); + } + +out: + if (rc != 0) + return rc; + + return count; +} +LPROC_SEQ_FOPS(nodemap_sepol); + +/** * Reads and prints the exports attached to the given nodemap. * * \param m seq file in proc fs, stores nodemap @@ -541,628 +608,95 @@ static int nodemap_deny_unknown_seq_show(struct seq_file *m, void *data) return 0; } -#ifdef NODEMAP_PROC_DEBUG -/** - * Helper functions to set nodemap flags. - * - * \param[in] buffer string, which is "1" or "0" to set/unset flag - * \param[in] count \a buffer length - * \param[out] flag_p where to store flag value - * \retval \a count on success - * \retval negative number on error - */ -static int nodemap_proc_read_flag(const char __user *buffer, - unsigned long count, unsigned int *flag_p) -{ - char scratch[NODEMAP_LPROC_FLAG_LEN + 1]; - long unsigned int flag_buf; - int rc; - - if (count == 0) - return 0; - - if (count >= sizeof(scratch)) - return -EINVAL; - - if (copy_from_user(scratch, buffer, count)) - return -EFAULT; - - scratch[count] = '\0'; - rc = kstrtoul(scratch, 10, &flag_buf); - if (rc != 0) - return -EINVAL; - - *flag_p = flag_buf; - - return count; -} - -/** - * Set the squash UID. - * - * \param[in] file proc file - * \param[in] buffer string representing squash UID to set - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error - */ -static ssize_t -nodemap_squash_uid_seq_write(struct file *file, const char __user *buffer, - size_t count, loff_t *off) -{ - char squash[NODEMAP_LPROC_ID_LEN + 1]; - struct seq_file *m = file->private_data; - long unsigned int squash_uid; - int rc; - - if (count == 0) - return 0; - - if (count >= sizeof(squash)) - return -EINVAL; - - if (copy_from_user(squash, buffer, count)) - return -EFAULT; - - squash[count] = '\0'; - rc = kstrtoul(squash, 10, &squash_uid); - if (rc != 0) - return -EINVAL; - - rc = nodemap_set_squash_uid(m->private, squash_uid); - if (rc != 0) - return rc; - - return count; -} - -/** - * Set the squash GID. - * - * \param[in] file proc file - * \param[in] buffer string representing squash GID to set - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error - */ -static ssize_t -nodemap_squash_gid_seq_write(struct file *file, const char __user *buffer, - size_t count, loff_t *off) -{ - char squash[NODEMAP_LPROC_ID_LEN + 1]; - struct seq_file *m = file->private_data; - long unsigned int squash_gid; - int rc; - - if (count == 0) - return 0; - - if (count >= sizeof(squash)) - return -EINVAL; - - if (copy_from_user(squash, buffer, count)) - return -EFAULT; - - squash[count] = '\0'; - rc = kstrtoul(squash, 10, &squash_gid); - if (rc != 0) - return -EINVAL; - - rc = nodemap_set_squash_gid(m->private, squash_gid); - if (rc != 0) - return rc; - - return count; -} - /** - * Set/unset the trusted flag. + * Reads and prints the audit_mode flag for the given nodemap. * - * \param[in] file proc file - * \param[in] buffer string, "1" or "0" - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error + * \param m seq file in proc fs + * \param data unused + * \retval 0 success */ -static ssize_t -nodemap_trusted_seq_write(struct file *file, const char __user *buffer, - size_t count, loff_t *off) +static int nodemap_audit_mode_seq_show(struct seq_file *m, void *data) { - struct seq_file *m = file->private_data; - int flags; - int rc; - - rc = nodemap_proc_read_flag(buffer, count, &flags); - if (rc < 0) - return rc; + struct lu_nodemap *nodemap; + int rc; - rc = nodemap_set_trust_client_ids(m->private, flags); - if (rc != 0) + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) { + rc = PTR_ERR(nodemap); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); return rc; + } - return count; + seq_printf(m, "%d\n", (int)nodemap->nmf_enable_audit); + nodemap_putref(nodemap); + return 0; } /** - * Set/unset the admin flag. + * Reads and prints the forbid_encryption flag for the given nodemap. * - * \param[in] file proc file - * \param[in] buffer string, "1" or "0" - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error + * \param m seq file in proc fs + * \param data unused + * \retval 0 success */ -static ssize_t -nodemap_admin_seq_write(struct file *file, const char __user *buffer, - size_t count, loff_t *off) +static int nodemap_forbid_encryption_seq_show(struct seq_file *m, void *data) { - struct seq_file *m = file->private_data; - int flags; - int rc; - - rc = nodemap_proc_read_flag(buffer, count, &flags); - if (rc < 0) - return rc; + struct lu_nodemap *nodemap; + int rc; - rc = nodemap_set_allow_root(m->private, flags); - if (rc != 0) + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) { + rc = PTR_ERR(nodemap); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); return rc; + } - return count; -} - -/** - * Add a nodemap. - * - * \param[in] file proc file - * \param[in] buffer string, name of the nodemap to add - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error - */ -static ssize_t -lprocfs_add_nodemap_seq_write(struct file *file, const char __user *buffer, - size_t count, loff_t *off) -{ - char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1]; - char *cpybuf = NULL; - char *pos; - int rc; - - if (count == 0) - return 0; - - if (count >= sizeof(nodemap_name)) - return -EINVAL; - - if (copy_from_user(nodemap_name, buffer, count)) - return -EFAULT; - - nodemap_name[count] = '\0'; - - cpybuf = nodemap_name; - pos = strsep(&cpybuf, " \n"); - if (pos == NULL) - return -EINVAL; - - rc = nodemap_add(nodemap_name); - if (rc == 0) - rc = count; - - return rc; -} -LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap); - -/** - * Delete a nodemap. - * - * \param[in] file proc file - * \param[in] buffer string, name of the nodemap to delete - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error - */ -static ssize_t -lprocfs_del_nodemap_seq_write(struct file *file, const char __user *buffer, - size_t count, loff_t *off) -{ - char nodemap_name[LUSTRE_NODEMAP_NAME_LENGTH + 1]; - char *cpybuf = NULL; - char *pos; - int rc = count; - - if (count == 0) - return 0; - - if (count >= sizeof(nodemap_name)) - return -EINVAL; - - if (copy_from_user(nodemap_name, buffer, count)) - return -EFAULT; - - nodemap_name[count] = '\0'; - - cpybuf = nodemap_name; - pos = strsep(&cpybuf, " \n"); - if (pos == NULL) - return -EINVAL; - - rc = nodemap_del(nodemap_name); - if (rc == 0) - rc = count; - - return rc; - -} -LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap); - -/** - * Helper function to parse a NID string. - * - * \param[in] rangestr string representation of NIDs, see libcfs_str2nid() - * \param[out] nids array of two nids - * \retval 0 on success - * \retval negative number on error - */ -static int parse_nids(char *rangestr, lnet_nid_t nids[2]) -{ - struct list_head nidlist; - char nidstr[2][LNET_NIDSTR_SIZE]; - char nidrange_str[2 * LNET_NIDSTR_SIZE + 2]; - int rc = 0; - - INIT_LIST_HEAD(&nidlist); - - if (cfs_parse_nidlist(rangestr, strlen(rangestr), - &nidlist) <= 0) - return -EINVAL; - - if (!cfs_nidrange_is_contiguous(&nidlist)) - return -EINVAL; - - cfs_nidrange_find_min_max(&nidlist, nidstr[0], nidstr[1], - LNET_NIDSTR_SIZE); - snprintf(nidrange_str, sizeof(nidrange_str), "%s:%s", - nidstr[0], nidstr[1]); - - rc = nodemap_parse_range(nidrange_str, nids); - if (rc != 0) - return -EINVAL; - - cfs_free_nidlist(&nidlist); - + seq_printf(m, "%d\n", (int)nodemap->nmf_forbid_encryption); + nodemap_putref(nodemap); return 0; } -/** - * Add a NID range to nodemap. - * - * \param[in] file proc file - * \param[in] buffer string, " " - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error - */ -static ssize_t -lprocfs_add_nodemap_range_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ - char name_range[LUSTRE_NODEMAP_NAME_LENGTH + - LNET_NIDSTR_SIZE * 2 + 2]; - char *cpybuf = NULL; - char *name; - char *rangestr = NULL; - lnet_nid_t nids[2]; - int rc; - - if (count == 0) - return 0; - - if (count >= sizeof(name_range)) - GOTO(out, rc = -EINVAL); - - if (copy_from_user(name_range, buffer, count)) - GOTO(out, rc = -EFAULT); - - name_range[count] = '\0'; - - cpybuf = name_range; - name = strsep(&cpybuf, " "); - if (name == NULL) - GOTO(out, rc = -EINVAL); - - rangestr = strsep(&cpybuf, " \n"); - if (rangestr == NULL) - GOTO(out, rc = -EINVAL); - - rc = parse_nids(rangestr, nids); - if (rc != 0) - GOTO(out, rc = rc); - - rc = nodemap_add_range(name, nids); - if (rc != 0) - GOTO(out, rc = -EINVAL); - - if (rc == 0) - rc = count; - -out: - return rc; -} -LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_range); - -/** - * Delete a NID range from nodemap. - * - * \param[in] file proc file - * \param[in] buffer string, " " - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error - */ -static ssize_t -lprocfs_del_nodemap_range_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ - char name_range[LUSTRE_NODEMAP_NAME_LENGTH + - LNET_NIDSTR_SIZE * 2 + 2]; - char *cpybuf = NULL; - char *name; - char *rangestr = NULL; - lnet_nid_t nids[2]; - int rc; - - if (count == 0) - return 0; - - if (count >= sizeof(name_range)) - GOTO(out, rc = -EINVAL); - - if (copy_from_user(name_range, buffer, count)) - GOTO(out, rc = -EFAULT); - - name_range[count] = '\0'; - - cpybuf = name_range; - name = strsep(&cpybuf, " "); - if (name == NULL) - GOTO(out, rc = -EINVAL); - - rangestr = strsep(&cpybuf, " \n"); - if (rangestr == NULL) - GOTO(out, rc = -EINVAL); - - rc = parse_nids(rangestr, nids); - if (rc != 0) - GOTO(out, rc = rc); - - rc = nodemap_del_range(name, nids); - if (rc != 0) - GOTO(out, rc = -EINVAL); - - if (rc == 0) - rc = count; - -out: - return rc; -} -LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_range); - -/** - * Add an idmap to nodemap. - * - * \param[in] file proc file - * \param[in] buffer string, " " - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error - */ -static ssize_t -lprocfs_add_nodemap_idmap_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ - char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16]; - char *cpybuf = NULL; - char *name; - char *idtypestr = NULL; - char *idmapstr = NULL; - __u32 idmap[2]; - int rc = count; - - if (count == 0) - return 0; - - if (count >= sizeof(name_idmapstr)) - GOTO(out, rc = -EINVAL); - - if (copy_from_user(name_idmapstr, buffer, count)) - GOTO(out, rc = -EFAULT); - - name_idmapstr[count] = '\0'; - - cpybuf = name_idmapstr; - name = strsep(&cpybuf, " "); - if (name == NULL) - GOTO(out, rc = -EINVAL); - - idtypestr = strsep(&cpybuf, " "); - if (idtypestr == NULL) - GOTO(out, rc = -EINVAL); - - idmapstr = strsep(&cpybuf, " \n"); - if (idmapstr == NULL) - GOTO(out, rc = -EINVAL); - - rc = nodemap_parse_idmap(idmapstr, idmap); - if (rc != 0) - GOTO(out, rc = -EINVAL); - - if (strcmp(idtypestr, "uid") == 0) - rc = nodemap_add_idmap(name, NODEMAP_UID, idmap); - else if (strcmp(idtypestr, "gid") == 0) - rc = nodemap_add_idmap(name, NODEMAP_GID, idmap); - else - GOTO(out, rc = -EINVAL); - - if (rc != 0) - GOTO(out, rc = -EINVAL); - - if (rc == 0) - rc = count; - -out: - return rc; -} -LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_idmap); - -/** - * Delete an idmap from nodemap. - * - * \param[in] file proc file - * \param[in] buffer string, " " - * \param[in] count \a buffer length - * \param[in] off unused - * \retval \a count on success - * \retval negative number on error - */ -static ssize_t -lprocfs_del_nodemap_idmap_seq_write(struct file *file, - const char __user *buffer, - size_t count, loff_t *off) -{ - char name_idmapstr[LUSTRE_NODEMAP_NAME_LENGTH + 16]; - char *cpybuf = NULL; - char *name; - char *idtypestr = NULL; - char *idmapstr = NULL; - __u32 idmap[2]; - int rc = count; - - if (count == 0) - return 0; - - if (count >= sizeof(name_idmapstr)) - GOTO(out, rc = -EINVAL); - - if (copy_from_user(name_idmapstr, buffer, count)) - GOTO(out, rc = -EFAULT); - - name_idmapstr[count] = '\0'; - - cpybuf = name_idmapstr; - name = strsep(&cpybuf, " "); - if (name == NULL) - GOTO(out, rc = -EINVAL); - - idtypestr = strsep(&cpybuf, " "); - if (idtypestr == NULL) - GOTO(out, rc = -EINVAL); - - idmapstr = strsep(&cpybuf, " \n"); - if (idmapstr == NULL) - GOTO(out, rc = -EINVAL); - - rc = nodemap_parse_idmap(idmapstr, idmap); - if (rc != 0) - GOTO(out, rc = -EINVAL); - - if (strcmp(idtypestr, "uid") == 0) - rc = nodemap_del_idmap(name, NODEMAP_UID, idmap); - else if (strcmp(idtypestr, "gid") == 0) - rc = nodemap_del_idmap(name, NODEMAP_GID, idmap); - else - GOTO(out, rc = -EINVAL); - - if (rc != 0) - GOTO(out, rc = -EINVAL); - - if (rc == 0) - rc = count; - -out: - return rc; -} -LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_idmap); -#endif /* NODEMAP_PROC_DEBUG */ - static struct lprocfs_vars lprocfs_nm_module_vars[] = { { .name = "active", .fops = &nodemap_active_fops, }, -#ifdef NODEMAP_PROC_DEBUG - { - .name = "add_nodemap", - .fops = &nodemap_add_nodemap_fops, - }, - { - .name = "remove_nodemap", - .fops = &nodemap_del_nodemap_fops, - }, - { - .name = "add_nodemap_range", - .fops = &nodemap_add_nodemap_range_fops, - }, - { - .name = "del_nodemap_range", - .fops = &nodemap_del_nodemap_range_fops, - }, - { - .name = "add_nodemap_idmap", - .fops = &nodemap_add_nodemap_idmap_fops, - }, - { - .name = "del_nodemap_idmap", - .fops = &nodemap_del_nodemap_idmap_fops, - }, -#endif /* NODEMAP_PROC_DEBUG */ { NULL } }; -#ifdef NODEMAP_PROC_DEBUG -LPROC_SEQ_FOPS(nodemap_trusted); -LPROC_SEQ_FOPS(nodemap_admin); -LPROC_SEQ_FOPS(nodemap_squash_uid); -LPROC_SEQ_FOPS(nodemap_squash_gid); -#else LPROC_SEQ_FOPS_RO(nodemap_trusted); LPROC_SEQ_FOPS_RO(nodemap_admin); LPROC_SEQ_FOPS_RO(nodemap_squash_uid); LPROC_SEQ_FOPS_RO(nodemap_squash_gid); -#endif LPROC_SEQ_FOPS_RO(nodemap_deny_unknown); LPROC_SEQ_FOPS_RO(nodemap_map_mode); +LPROC_SEQ_FOPS_RO(nodemap_audit_mode); +LPROC_SEQ_FOPS_RO(nodemap_forbid_encryption); -const struct file_operations nodemap_ranges_fops = { +static const struct file_operations nodemap_ranges_fops = { .open = nodemap_ranges_open, .read = seq_read, .llseek = seq_lseek, .release = single_release }; -const struct file_operations nodemap_idmap_fops = { +static const struct file_operations nodemap_idmap_fops = { .open = nodemap_idmap_open, .read = seq_read, .llseek = seq_lseek, .release = single_release }; -const struct file_operations nodemap_exports_fops = { +static const struct file_operations nodemap_exports_fops = { .open = nodemap_exports_open, .read = seq_read, .llseek = seq_lseek, @@ -1191,6 +725,14 @@ static struct lprocfs_vars lprocfs_nodemap_vars[] = { .fops = &nodemap_map_mode_fops, }, { + .name = "audit_mode", + .fops = &nodemap_audit_mode_fops, + }, + { + .name = "forbid_encryption", + .fops = &nodemap_forbid_encryption_fops, + }, + { .name = "squash_uid", .fops = &nodemap_squash_uid_fops, }, @@ -1207,6 +749,10 @@ static struct lprocfs_vars lprocfs_nodemap_vars[] = { .fops = &nodemap_fileset_fops, }, { + .name = "sepol", + .fops = &nodemap_sepol_fops, + }, + { .name = "exports", .fops = &nodemap_exports_fops, }, @@ -1233,6 +779,10 @@ static struct lprocfs_vars lprocfs_default_nodemap_vars[] = { .fops = &nodemap_admin_fops, }, { + .name = "deny_unknown", + .fops = &nodemap_deny_unknown_fops, + }, + { .name = "squash_uid", .fops = &nodemap_squash_uid_fops, }, @@ -1241,10 +791,22 @@ static struct lprocfs_vars lprocfs_default_nodemap_vars[] = { .fops = &nodemap_squash_gid_fops, }, { + .name = "fileset", + .fops = &nodemap_fileset_fops, + }, + { .name = "exports", .fops = &nodemap_exports_fops, }, { + .name = "audit_mode", + .fops = &nodemap_audit_mode_fops, + }, + { + .name = "forbid_encryption", + .fops = &nodemap_forbid_encryption_fops, + }, + { NULL } };