X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fnodemap_lproc.c;h=fc13b004cd2945c01769322ca64da85d6f945dae;hb=3af10d510078ddf050fbda2ef80bdc6920d89f8d;hp=9f3b742189d1f3621b21f20b205cd9ea3f3d5a68;hpb=a172863af11bcef474191ca40eaa479179457c08;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/nodemap_lproc.c b/lustre/ptlrpc/nodemap_lproc.c index 9f3b742..fc13b00 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, Intel Corporation. + * Copyright (c) 2014, 2015, Intel Corporation. * * Author: Joshua Walgenbach */ @@ -37,11 +37,7 @@ #include #include "nodemap_internal.h" -/* Turn on proc debug interface to allow OSS and - * MDS nodes to configure nodemap independently of - * MGS (since the nodemap distribution is not written - * yet */ -#define NODEMAP_PROC_DEBUG 1 +static LIST_HEAD(nodemap_pde_list); /** * Reads and prints the idmap for the given nodemap. @@ -52,10 +48,21 @@ */ static int nodemap_idmap_show(struct seq_file *m, void *data) { - struct lu_nodemap *nodemap = m->private; + struct lu_nodemap *nodemap; struct lu_idmap *idmap; struct rb_node *node; bool cont = 0; + int rc; + + 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, "[\n"); read_lock(&nodemap->nm_idmap_lock); @@ -84,6 +91,7 @@ static int nodemap_idmap_show(struct seq_file *m, void *data) seq_printf(m, "\n"); seq_printf(m, "]\n"); + nodemap_putref(nodemap); return 0; } @@ -96,9 +104,7 @@ static int nodemap_idmap_show(struct seq_file *m, void *data) */ static int nodemap_idmap_open(struct inode *inode, struct file *file) { - struct lu_nodemap *nodemap = PDE_DATA(inode); - - return single_open(file, nodemap_idmap_show, nodemap); + return single_open(file, nodemap_idmap_show, PDE_DATA(inode)); } /** @@ -110,27 +116,42 @@ static int nodemap_idmap_open(struct inode *inode, struct file *file) */ static int nodemap_ranges_show(struct seq_file *m, void *data) { - struct lu_nodemap *nodemap = m->private; + 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; + int rc; + + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + if (IS_ERR(nodemap)) { + mutex_unlock(&active_config_lock); + rc = PTR_ERR(nodemap); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); + return rc; + } seq_printf(m, "[\n"); - read_lock(&nm_range_tree_lock); + down_read(&active_config->nmc_range_tree_lock); list_for_each_entry(range, &nodemap->nm_ranges, rn_list) { if (cont) seq_printf(m, ",\n"); cont = 1; ext = range->rn_node.in_extent; - seq_printf(m, " { id: %u, start_nid: %s, " - "end_nid: %s }", - range->rn_id, libcfs_nid2str(ext.start), - libcfs_nid2str(ext.end)); + libcfs_nid2str_r(ext.start, start_nidstr, sizeof(start_nidstr)); + libcfs_nid2str_r(ext.end, end_nidstr, sizeof(end_nidstr)); + seq_printf(m, " { id: %u, start_nid: %s, end_nid: %s }", + range->rn_id, start_nidstr, end_nidstr); } - read_unlock(&nm_range_tree_lock); + up_read(&active_config->nmc_range_tree_lock); + mutex_unlock(&active_config_lock); seq_printf(m, "\n"); seq_printf(m, "]\n"); + nodemap_putref(nodemap); return 0; } @@ -143,55 +164,124 @@ static int nodemap_ranges_show(struct seq_file *m, void *data) */ static int nodemap_ranges_open(struct inode *inode, struct file *file) { - struct lu_nodemap *nodemap = PDE_DATA(inode); - - return single_open(file, nodemap_ranges_show, nodemap); + return single_open(file, nodemap_ranges_show, PDE_DATA(inode)); } /** - * Hash callback, reads and prints the exports attached to this nodemap. + * Reads and prints the fileset for the given nodemap. * - * \param hs nodemap member hash - * \param bd unused - * \param hnode current member in hash - * \param data seq_file to print to + * \param m seq file in proc fs + * \param data unused * \retval 0 success */ -static int nodemap_exports_show_cb(cfs_hash_t *hs, cfs_hash_bd_t *bd, - struct hlist_node *hnode, void *data) +static int nodemap_fileset_seq_show(struct seq_file *m, void *data) { - struct seq_file *m = data; - struct obd_export *exp; - char *key; + struct lu_nodemap *nodemap; + int rc = 0; - exp = hlist_entry(hnode, struct obd_export, - exp_target_data.ted_nodemap_member); - key = cfs_hash_key(hs, hnode); - seq_printf(m, " { nid: %s, uuid: %s },", - obd_export_nid2str(exp), exp->exp_client_uuid.uuid); + 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 0; + seq_printf(m, "%s\n", nodemap->nm_fileset); + nodemap_putref(nodemap); + return rc; } /** - * Reads and prints the exports attached to the given nodemap via hash - * foreach callback. + * Set a fileset on a nodemap. * - * \param m seq file in proc fs + * \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_fileset_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) +{ + struct seq_file *m = file->private_data; + char *nm_fileset; + int rc = 0; + ENTRY; + + if (count == 0) + RETURN(0); + + if (count > PATH_MAX) + RETURN(-EINVAL); + + OBD_ALLOC(nm_fileset, count + 1); + /* OBD_ALLOC zero-fills the buffer */ + if (nm_fileset == NULL) + RETURN(-ENOMEM); + + if (copy_from_user(nm_fileset, buffer, count)) + GOTO(out, rc = -EFAULT); + + rc = nodemap_set_fileset(m->private, nm_fileset); + if (rc != 0) + GOTO(out, rc = -EINVAL); + + rc = count; +out: + OBD_FREE(nm_fileset, count + 1); + + return rc; +} +LPROC_SEQ_FOPS(nodemap_fileset); + +/** + * Reads and prints the exports attached to the given nodemap. + * + * \param m seq file in proc fs, stores nodemap * \param data unused * \retval 0 success */ static int nodemap_exports_show(struct seq_file *m, void *data) { - struct lu_nodemap *nodemap = m->private; + struct lu_nodemap *nodemap; + struct obd_export *exp; + char nidstr[LNET_NIDSTR_SIZE] = ""; + int rc; + + 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, "[\n"); - cfs_hash_for_each(nodemap->nm_member_hash, nodemap_exports_show_cb, m); + mutex_lock(&nodemap->nm_member_list_lock); + list_for_each_entry(exp, &nodemap->nm_member_list, + exp_target_data.ted_nodemap_member) { + if (exp->exp_connection != NULL) + libcfs_nid2str_r(exp->exp_connection->c_peer.nid, + nidstr, sizeof(nidstr)); + + seq_printf(m, " { nid: %s, uuid: %s },", + nidstr, exp->exp_client_uuid.uuid); + } + mutex_unlock(&nodemap->nm_member_list_lock); seq_printf(m, "\n"); seq_printf(m, "]\n"); + nodemap_putref(nodemap); return 0; } @@ -204,9 +294,7 @@ static int nodemap_exports_show(struct seq_file *m, void *data) */ static int nodemap_exports_open(struct inode *inode, struct file *file) { - struct lu_nodemap *nodemap = PDE_DATA(inode); - - return single_open(file, nodemap_exports_show, nodemap); + return single_open(file, nodemap_exports_show, PDE_DATA(inode)); } /** @@ -218,7 +306,8 @@ static int nodemap_exports_open(struct inode *inode, struct file *file) */ static int nodemap_active_seq_show(struct seq_file *m, void *data) { - return seq_printf(m, "%u\n", (unsigned int)nodemap_active); + seq_printf(m, "%u\n", (unsigned int)nodemap_active); + return 0; } /** @@ -253,7 +342,7 @@ nodemap_active_seq_write(struct file *file, const char __user *buffer, if (rc != 0) return -EINVAL; - nodemap_active = active; + nodemap_activate(active); return count; } @@ -268,9 +357,21 @@ LPROC_SEQ_FOPS(nodemap_active); */ static int nodemap_id_seq_show(struct seq_file *m, void *data) { - struct lu_nodemap *nodemap = m->private; + struct lu_nodemap *nodemap; + + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) { + int rc = PTR_ERR(nodemap); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); + return rc; + } - return seq_printf(m, "%u\n", nodemap->nm_id); + seq_printf(m, "%u\n", nodemap->nm_id); + nodemap_putref(nodemap); + return 0; } LPROC_SEQ_FOPS_RO(nodemap_id); @@ -283,9 +384,21 @@ LPROC_SEQ_FOPS_RO(nodemap_id); */ static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data) { - struct lu_nodemap *nodemap = m->private; + struct lu_nodemap *nodemap; + + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) { + int rc = PTR_ERR(nodemap); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); + return rc; + } - return seq_printf(m, "%u\n", nodemap->nm_squash_uid); + seq_printf(m, "%u\n", nodemap->nm_squash_uid); + nodemap_putref(nodemap); + return 0; } /** @@ -297,9 +410,21 @@ static int nodemap_squash_uid_seq_show(struct seq_file *m, void *data) */ static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data) { - struct lu_nodemap *nodemap = m->private; + struct lu_nodemap *nodemap; + + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) { + int rc = PTR_ERR(nodemap); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); + return rc; + } - return seq_printf(m, "%u\n", nodemap->nm_squash_gid); + seq_printf(m, "%u\n", nodemap->nm_squash_gid); + nodemap_putref(nodemap); + return 0; } /** @@ -311,9 +436,22 @@ static int nodemap_squash_gid_seq_show(struct seq_file *m, void *data) */ static int nodemap_trusted_seq_show(struct seq_file *m, void *data) { - struct lu_nodemap *nodemap = m->private; + struct lu_nodemap *nodemap; + + mutex_lock(&active_config_lock); + nodemap = nodemap_lookup(m->private); + mutex_unlock(&active_config_lock); + if (IS_ERR(nodemap)) { + int rc = PTR_ERR(nodemap); + + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); + return rc; + } - return seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids); + seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids); + nodemap_putref(nodemap); + return 0; } /** @@ -325,9 +463,82 @@ static int nodemap_trusted_seq_show(struct seq_file *m, void *data) */ static int nodemap_admin_seq_show(struct seq_file *m, void *data) { - struct lu_nodemap *nodemap = m->private; + struct lu_nodemap *nodemap; + int rc; + + 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 seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access); + seq_printf(m, "%d\n", (int)nodemap->nmf_allow_root_access); + nodemap_putref(nodemap); + return 0; +} + +/** + * Reads and prints the mapping mode for the given nodemap. + * + * \param m seq file in proc fs + * \param data unused + * \retval 0 success + */ +static int nodemap_map_mode_seq_show(struct seq_file *m, void *data) +{ + struct lu_nodemap *nodemap; + int rc; + + 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; + } + + if (nodemap->nmf_map_uid_only) + seq_printf(m, "uid_only\n"); + else if (nodemap->nmf_map_gid_only) + seq_printf(m, "gid_only\n"); + else + seq_printf(m, "both\n"); + + nodemap_putref(nodemap); + return 0; +} + +/** + * Reads and prints the deny_unknown flag for the given nodemap. + * + * \param m seq file in proc fs + * \param data unused + * \retval 0 success + */ +static int nodemap_deny_unknown_seq_show(struct seq_file *m, void *data) +{ + struct lu_nodemap *nodemap; + int rc; + + 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, "%d\n", (int)nodemap->nmf_deny_unknown); + nodemap_putref(nodemap); + return 0; } #ifdef NODEMAP_PROC_DEBUG @@ -382,7 +593,6 @@ nodemap_squash_uid_seq_write(struct file *file, const char __user *buffer, { char squash[NODEMAP_LPROC_ID_LEN + 1]; struct seq_file *m = file->private_data; - struct lu_nodemap *nodemap = m->private; long unsigned int squash_uid; int rc; @@ -400,7 +610,9 @@ nodemap_squash_uid_seq_write(struct file *file, const char __user *buffer, if (rc != 0) return -EINVAL; - nodemap->nm_squash_uid = squash_uid; + rc = nodemap_set_squash_uid(m->private, squash_uid); + if (rc != 0) + return rc; return count; } @@ -421,7 +633,6 @@ nodemap_squash_gid_seq_write(struct file *file, const char __user *buffer, { char squash[NODEMAP_LPROC_ID_LEN + 1]; struct seq_file *m = file->private_data; - struct lu_nodemap *nodemap = m->private; long unsigned int squash_gid; int rc; @@ -439,7 +650,9 @@ nodemap_squash_gid_seq_write(struct file *file, const char __user *buffer, if (rc != 0) return -EINVAL; - nodemap->nm_squash_gid = squash_gid; + rc = nodemap_set_squash_gid(m->private, squash_gid); + if (rc != 0) + return rc; return count; } @@ -459,17 +672,18 @@ nodemap_trusted_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct seq_file *m = file->private_data; - struct lu_nodemap *nodemap = m->private; int flags; int rc; rc = nodemap_proc_read_flag(buffer, count, &flags); - if (rc >= 0) { - nodemap->nmf_trust_client_ids = !!flags; - nm_member_revoke_locks(nodemap); - } + if (rc < 0) + return rc; - return rc; + rc = nodemap_set_trust_client_ids(m->private, flags); + if (rc != 0) + return rc; + + return count; } /** @@ -487,17 +701,18 @@ nodemap_admin_seq_write(struct file *file, const char __user *buffer, size_t count, loff_t *off) { struct seq_file *m = file->private_data; - struct lu_nodemap *nodemap = m->private; int flags; int rc; rc = nodemap_proc_read_flag(buffer, count, &flags); - if (rc >= 0) { - nodemap->nmf_allow_root_access = !!flags; - nm_member_revoke_locks(nodemap); - } + if (rc < 0) + return rc; - return rc; + rc = nodemap_set_allow_root(m->private, flags); + if (rc != 0) + return rc; + + return count; } /** @@ -541,7 +756,7 @@ lprocfs_add_nodemap_seq_write(struct file *file, const char __user *buffer, return rc; } -LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap); +LPROC_SEQ_FOPS_WR_ONLY(nodemap, add_nodemap); /** * Delete a nodemap. @@ -585,7 +800,7 @@ lprocfs_del_nodemap_seq_write(struct file *file, const char __user *buffer, return rc; } -LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap); +LPROC_SEQ_FOPS_WR_ONLY(nodemap, del_nodemap); /** * Helper function to parse a NID string. @@ -682,7 +897,7 @@ lprocfs_add_nodemap_range_seq_write(struct file *file, out: return rc; } -LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_range); +LPROC_SEQ_FOPS_WR_ONLY(nodemap, add_nodemap_range); /** * Delete a NID range from nodemap. @@ -741,7 +956,7 @@ lprocfs_del_nodemap_range_seq_write(struct file *file, out: return rc; } -LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_range); +LPROC_SEQ_FOPS_WR_ONLY(nodemap, del_nodemap_range); /** * Add an idmap to nodemap. @@ -810,7 +1025,7 @@ lprocfs_add_nodemap_idmap_seq_write(struct file *file, out: return rc; } -LPROC_SEQ_FOPS_WO_TYPE(nodemap, add_nodemap_idmap); +LPROC_SEQ_FOPS_WR_ONLY(nodemap, add_nodemap_idmap); /** * Delete an idmap from nodemap. @@ -879,7 +1094,7 @@ lprocfs_del_nodemap_idmap_seq_write(struct file *file, out: return rc; } -LPROC_SEQ_FOPS_WO_TYPE(nodemap, del_nodemap_idmap); +LPROC_SEQ_FOPS_WR_ONLY(nodemap, del_nodemap_idmap); #endif /* NODEMAP_PROC_DEBUG */ static struct lprocfs_vars lprocfs_nm_module_vars[] = { @@ -930,6 +1145,9 @@ 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); + const struct file_operations nodemap_ranges_fops = { .open = nodemap_ranges_open, .read = seq_read, @@ -965,6 +1183,14 @@ static struct lprocfs_vars lprocfs_nodemap_vars[] = { .fops = &nodemap_admin_fops, }, { + .name = "deny_unknown", + .fops = &nodemap_deny_unknown_fops, + }, + { + .name = "map_mode", + .fops = &nodemap_map_mode_fops, + }, + { .name = "squash_uid", .fops = &nodemap_squash_uid_fops, }, @@ -977,6 +1203,10 @@ static struct lprocfs_vars lprocfs_nodemap_vars[] = { .fops = &nodemap_ranges_fops, }, { + .name = "fileset", + .fops = &nodemap_fileset_fops, + }, + { .name = "exports", .fops = &nodemap_exports_fops, }, @@ -1042,37 +1272,79 @@ int nodemap_procfs_init(void) } /** + * Cleanup nodemap proc entry data structures. + */ +void nodemap_procfs_exit(void) +{ + struct nodemap_pde *nm_pde; + struct nodemap_pde *tmp; + + lprocfs_remove(&proc_lustre_nodemap_root); + list_for_each_entry_safe(nm_pde, tmp, &nodemap_pde_list, + npe_list_member) { + list_del(&nm_pde->npe_list_member); + OBD_FREE_PTR(nm_pde); + } +} + +/** + * Remove a nodemap's procfs entry and related data. + */ +void lprocfs_nodemap_remove(struct nodemap_pde *nm_pde) +{ + lprocfs_remove(&nm_pde->npe_proc_entry); + list_del(&nm_pde->npe_list_member); + OBD_FREE_PTR(nm_pde); +} + +/** * Register the proc directory for a nodemap * - * \param name name of nodemap + * \param nodemap nodemap to make the proc dir for * \param is_default: 1 if default nodemap * \retval 0 success */ -int lprocfs_nodemap_register(const char *name, - bool is_default, - struct lu_nodemap *nodemap) +int lprocfs_nodemap_register(struct lu_nodemap *nodemap, bool is_default) { - struct proc_dir_entry *nodemap_proc_entry; - int rc = 0; - - if (is_default) - nodemap_proc_entry = - lprocfs_register(name, proc_lustre_nodemap_root, - lprocfs_default_nodemap_vars, - nodemap); + struct nodemap_pde *nm_entry; + int rc = 0; + + OBD_ALLOC_PTR(nm_entry); + if (nm_entry == NULL) + GOTO(out, rc = -ENOMEM); + + nm_entry->npe_proc_entry = proc_mkdir(nodemap->nm_name, + proc_lustre_nodemap_root); + if (IS_ERR(nm_entry->npe_proc_entry)) + GOTO(out, rc = PTR_ERR(nm_entry->npe_proc_entry)); + + snprintf(nm_entry->npe_name, sizeof(nm_entry->npe_name), "%s", + nodemap->nm_name); + + /* Use the nodemap name as stored on the PDE as the private data. This + * is so a nodemap struct can be replaced without updating the proc + * entries. + */ + rc = lprocfs_add_vars(nm_entry->npe_proc_entry, + (is_default ? lprocfs_default_nodemap_vars : + lprocfs_nodemap_vars), + nm_entry->npe_name); + if (rc != 0) + lprocfs_remove(&nm_entry->npe_proc_entry); else - nodemap_proc_entry = - lprocfs_register(name, proc_lustre_nodemap_root, - lprocfs_nodemap_vars, - nodemap); - - if (IS_ERR(nodemap_proc_entry)) { - rc = PTR_ERR(nodemap_proc_entry); - CERROR("cannot create 'nodemap/%s': rc = %d\n", name, rc); - nodemap_proc_entry = NULL; + list_add(&nm_entry->npe_list_member, &nodemap_pde_list); + +out: + if (rc != 0) { + CERROR("cannot create 'nodemap/%s': rc = %d\n", + nodemap->nm_name, rc); + if (nm_entry != NULL) { + OBD_FREE_PTR(nm_entry); + nm_entry = NULL; + } } - nodemap->nm_proc_entry = nodemap_proc_entry; + nodemap->nm_pde_data = nm_entry; return rc; }