X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fnodemap_lproc.c;h=fa6a6a7f455e21da8c3b961a4451e8911d39d574;hb=3be9beb00e7cca9d758b364a85537b0631dddc12;hp=0f4cfe4dc0fd31c39e06c63fe714a4dbb22d4c26;hpb=0ad4f8a4227ed7dd93fec99d33c6bb25056473fc;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/nodemap_lproc.c b/lustre/ptlrpc/nodemap_lproc.c index 0f4cfe4..fa6a6a7 100644 --- a/lustre/ptlrpc/nodemap_lproc.c +++ b/lustre/ptlrpc/nodemap_lproc.c @@ -21,6 +21,9 @@ */ /* * Copyright (C) 2013, Trustees of Indiana University + * + * Copyright (c) 2014, 2015, Intel Corporation. + * * Author: Joshua Walgenbach */ @@ -34,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. @@ -49,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); @@ -81,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; } @@ -93,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)); } /** @@ -107,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; } @@ -140,55 +164,106 @@ 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; + + 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; + } - 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); + rc = seq_printf(m, "%s\n", nodemap->nm_fileset); + nodemap_putref(nodemap); + return rc; +} - return 0; +/** + * Set a fileset 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_fileset_seq_write(struct file *file, + const char __user *buffer, + size_t count, loff_t *off) +{ + struct seq_file *m = file->private_data; + int rc = 0; + + if (count > 0) + rc = nodemap_set_fileset(m->private, buffer); + + if (rc != 0) + return -EINVAL; + + return count; } +LPROC_SEQ_FOPS(nodemap_fileset); /** - * Reads and prints the exports attached to the given nodemap via hash - * foreach callback. + * Reads and prints the exports attached to the given nodemap. * - * \param m seq file in proc fs + * \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; } @@ -201,9 +276,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)); } /** @@ -215,7 +288,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; } /** @@ -250,7 +324,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; } @@ -265,9 +339,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); @@ -280,9 +366,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; } /** @@ -294,9 +392,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; } /** @@ -308,9 +418,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); - return seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids); + CERROR("cannot find nodemap '%s': rc = %d\n", + (char *)m->private, rc); + return rc; + } + + seq_printf(m, "%d\n", (int)nodemap->nmf_trust_client_ids); + nodemap_putref(nodemap); + return 0; } /** @@ -322,9 +445,22 @@ 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; } #ifdef NODEMAP_PROC_DEBUG @@ -379,7 +515,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; @@ -397,7 +532,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; } @@ -418,7 +555,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; @@ -436,7 +572,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; } @@ -456,17 +594,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; } /** @@ -484,17 +623,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; } /** @@ -974,6 +1114,10 @@ static struct lprocfs_vars lprocfs_nodemap_vars[] = { .fops = &nodemap_ranges_fops, }, { + .name = "fileset", + .fops = &nodemap_fileset_fops, + }, + { .name = "exports", .fops = &nodemap_exports_fops, }, @@ -1029,46 +1173,89 @@ int nodemap_procfs_init(void) proc_lustre_root, lprocfs_nm_module_vars, NULL); - if (IS_ERR(proc_lustre_nodemap_root)) { rc = PTR_ERR(proc_lustre_nodemap_root); CERROR("cannot create 'nodemap' directory: rc = %d\n", rc); proc_lustre_nodemap_root = NULL; } - return rc; } /** + * 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; - struct lprocfs_vars *vars; - int rc = 0; - - if (is_default) - vars = lprocfs_default_nodemap_vars; + 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 - vars = lprocfs_nodemap_vars; - - nodemap_proc_entry = lprocfs_register(name, proc_lustre_nodemap_root, - 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; }