X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fsec_config.c;h=050003a7beba44662e0894ad82f9bfa443a7d51f;hb=62ca9b823524ca44d3344b2555754890abc55a3b;hp=e0b8ebb082838db08ab41ac1a597f5b40026f45e;hpb=2d617260aaa5f778ab8dcb006e2a827f4b8f8567;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/sec_config.c b/lustre/ptlrpc/sec_config.c index e0b8ebb..050003a 100644 --- a/lustre/ptlrpc/sec_config.c +++ b/lustre/ptlrpc/sec_config.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, Whamcloud, Inc. + * Copyright (c) 2011, 2016, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -37,13 +33,8 @@ #define DEBUG_SUBSYSTEM S_SEC #include -#ifndef __KERNEL__ -#include -#include -#else #include #include -#endif #include #include @@ -53,7 +44,7 @@ #include #include #include -#include +#include #include #include "ptlrpc_internal.h" @@ -93,7 +84,6 @@ enum lustre_sec_part sptlrpc_target_sec_part(struct obd_device *obd) CERROR("unknown target %p(%s)\n", obd, type); return LUSTRE_SP_ANY; } -EXPORT_SYMBOL(sptlrpc_target_sec_part); /**************************************** * user supplied flavor string parsing * @@ -114,8 +104,7 @@ int sptlrpc_parse_flavor(const char *str, struct sptlrpc_flavor *flvr) return 0; } - strncpy(buf, str, sizeof(buf)); - buf[sizeof(buf) - 1] = '\0'; + strlcpy(buf, str, sizeof(buf)); bulk = strchr(buf, '-'); if (bulk) @@ -264,15 +253,15 @@ EXPORT_SYMBOL(sptlrpc_rule_set_free); */ int sptlrpc_rule_set_expand(struct sptlrpc_rule_set *rset) { - struct sptlrpc_rule *rules; - int nslot; + struct sptlrpc_rule *rules; + int nslot; - cfs_might_sleep(); + might_sleep(); - if (rset->srs_nrule < rset->srs_nslot) - return 0; + if (rset->srs_nrule < rset->srs_nslot) + return 0; - nslot = rset->srs_nslot + 8; + nslot = rset->srs_nslot + 8; /* better use realloc() if available */ OBD_ALLOC(rules, nslot * sizeof(*rset->srs_rules)); @@ -292,7 +281,6 @@ int sptlrpc_rule_set_expand(struct sptlrpc_rule_set *rset) rset->srs_nslot = nslot; return 0; } -EXPORT_SYMBOL(sptlrpc_rule_set_expand); static inline int rule_spec_dir(struct sptlrpc_rule *rule) { @@ -321,14 +309,14 @@ static inline int rule_match_net(struct sptlrpc_rule *r1, int sptlrpc_rule_set_merge(struct sptlrpc_rule_set *rset, struct sptlrpc_rule *rule) { - struct sptlrpc_rule *p = rset->srs_rules; - int spec_dir, spec_net; - int rc, n, match = 0; + struct sptlrpc_rule *p = rset->srs_rules; + int spec_dir, spec_net; + int rc, n, match = 0; - cfs_might_sleep(); + might_sleep(); - spec_net = rule_spec_net(rule); - spec_dir = rule_spec_dir(rule); + spec_net = rule_spec_net(rule); + spec_dir = rule_spec_dir(rule); for (n = 0; n < rset->srs_nrule; n++) { p = &rset->srs_rules[n]; @@ -440,7 +428,6 @@ int sptlrpc_rule_set_choose(struct sptlrpc_rule_set *rset, return 0; } -EXPORT_SYMBOL(sptlrpc_rule_set_choose); void sptlrpc_rule_set_dump(struct sptlrpc_rule_set *rset) { @@ -453,7 +440,6 @@ void sptlrpc_rule_set_dump(struct sptlrpc_rule_set *rset) r->sr_from, r->sr_to, r->sr_netid, r->sr_flvr.sf_rpc); } } -EXPORT_SYMBOL(sptlrpc_rule_set_dump); static int sptlrpc_rule_set_extract(struct sptlrpc_rule_set *gen, struct sptlrpc_rule_set *tgt, @@ -461,16 +447,16 @@ static int sptlrpc_rule_set_extract(struct sptlrpc_rule_set *gen, enum lustre_sec_part to, struct sptlrpc_rule_set *rset) { - struct sptlrpc_rule_set *src[2] = { gen, tgt }; - struct sptlrpc_rule *rule; - int i, n, rc; + struct sptlrpc_rule_set *src[2] = { gen, tgt }; + struct sptlrpc_rule *rule; + int i, n, rc; - cfs_might_sleep(); + might_sleep(); - /* merge general rules firstly, then target-specific rules */ - for (i = 0; i < 2; i++) { - if (src[i] == NULL) - continue; + /* merge general rules firstly, then target-specific rules */ + for (i = 0; i < 2; i++) { + if (src[i] == NULL) + continue; for (n = 0; n < src[i]->srs_nrule; n++) { rule = &src[i]->srs_rules[n]; @@ -500,44 +486,56 @@ static int sptlrpc_rule_set_extract(struct sptlrpc_rule_set *gen, **********************************/ struct sptlrpc_conf_tgt { - cfs_list_t sct_list; + struct list_head sct_list; char sct_name[MAX_OBD_NAME]; struct sptlrpc_rule_set sct_rset; }; struct sptlrpc_conf { - cfs_list_t sc_list; - char sc_fsname[MTI_NAME_MAXLEN]; - unsigned int sc_modified; /* modified during updating */ - unsigned int sc_updated:1, /* updated copy from MGS */ - sc_local:1; /* local copy from target */ - struct sptlrpc_rule_set sc_rset; /* fs general rules */ - cfs_list_t sc_tgts; /* target-specific rules */ + struct list_head sc_list; + char sc_fsname[MTI_NAME_MAXLEN]; + unsigned int sc_modified; /* modified during updating */ + unsigned int sc_updated:1, /* updated copy from MGS */ + sc_local:1; /* local copy from target */ + struct sptlrpc_rule_set sc_rset; /* fs general rules */ + struct list_head sc_tgts; /* target-specific rules */ }; -static cfs_mutex_t sptlrpc_conf_lock; -static CFS_LIST_HEAD(sptlrpc_confs); - -static inline int is_hex(char c) -{ - return ((c >= '0' && c <= '9') || - (c >= 'a' && c <= 'f')); -} +static struct mutex sptlrpc_conf_lock; +static struct list_head sptlrpc_confs; -static void target2fsname(const char *tgt, char *fsname, int buflen) -{ - const char *ptr; - int len; - - ptr = strrchr(tgt, '-'); - if (ptr) { - if ((strncmp(ptr, "-MDT", 4) != 0 && - strncmp(ptr, "-OST", 4) != 0) || - !is_hex(ptr[4]) || !is_hex(ptr[5]) || - !is_hex(ptr[6]) || !is_hex(ptr[7])) - ptr = NULL; - } +/* + * The goal of this function is to extract the file system name + * from the obd name. This can come in two flavors. One is + * fsname-MDTXXXX or fsname-XXXXXXX were X is a hexadecimal + * number. In both cases we should be returned fsname. If it is + * not a valid obd name it is assumed to be the file system + * name itself. + */ +static void obdname2fsname(const char *tgt, char *fsname, size_t buflen) +{ + const char *ptr; + size_t len; + + ptr = strrchr(tgt, '-'); + if (ptr) { + if ((!strncmp(ptr, "-MDT", 4) || + !strncmp(ptr, "-OST", 4)) && + (isxdigit(ptr[4]) && isxdigit(ptr[5]) && + isxdigit(ptr[6]) && isxdigit(ptr[7]))) + goto valid_obd_name; + + /* The length of the obdname can vary on different platforms */ + len = strlen(ptr); + while (--len) { + if (!isxdigit(ptr[len])) { + ptr = NULL; + break; + } + } + } +valid_obd_name: /* if we didn't find the pattern, treat the whole string as fsname */ if (ptr == NULL) len = strlen(tgt); @@ -551,29 +549,29 @@ static void target2fsname(const char *tgt, char *fsname, int buflen) static void sptlrpc_conf_free_rsets(struct sptlrpc_conf *conf) { - struct sptlrpc_conf_tgt *conf_tgt, *conf_tgt_next; + struct sptlrpc_conf_tgt *conf_tgt, *conf_tgt_next; - sptlrpc_rule_set_free(&conf->sc_rset); + sptlrpc_rule_set_free(&conf->sc_rset); - cfs_list_for_each_entry_safe(conf_tgt, conf_tgt_next, - &conf->sc_tgts, sct_list) { - sptlrpc_rule_set_free(&conf_tgt->sct_rset); - cfs_list_del(&conf_tgt->sct_list); - OBD_FREE_PTR(conf_tgt); - } - LASSERT(cfs_list_empty(&conf->sc_tgts)); + list_for_each_entry_safe(conf_tgt, conf_tgt_next, + &conf->sc_tgts, sct_list) { + sptlrpc_rule_set_free(&conf_tgt->sct_rset); + list_del(&conf_tgt->sct_list); + OBD_FREE_PTR(conf_tgt); + } + LASSERT(list_empty(&conf->sc_tgts)); - conf->sc_updated = 0; - conf->sc_local = 0; + conf->sc_updated = 0; + conf->sc_local = 0; } static void sptlrpc_conf_free(struct sptlrpc_conf *conf) { - CDEBUG(D_SEC, "free sptlrpc conf %s\n", conf->sc_fsname); + CDEBUG(D_SEC, "free sptlrpc conf %s\n", conf->sc_fsname); - sptlrpc_conf_free_rsets(conf); - cfs_list_del(&conf->sc_list); - OBD_FREE_PTR(conf); + sptlrpc_conf_free_rsets(conf); + list_del(&conf->sc_list); + OBD_FREE_PTR(conf); } static @@ -583,7 +581,7 @@ struct sptlrpc_conf_tgt *sptlrpc_conf_get_tgt(struct sptlrpc_conf *conf, { struct sptlrpc_conf_tgt *conf_tgt; - cfs_list_for_each_entry(conf_tgt, &conf->sc_tgts, sct_list) { + list_for_each_entry(conf_tgt, &conf->sc_tgts, sct_list) { if (strcmp(conf_tgt->sct_name, name) == 0) return conf_tgt; } @@ -593,9 +591,9 @@ struct sptlrpc_conf_tgt *sptlrpc_conf_get_tgt(struct sptlrpc_conf *conf, OBD_ALLOC_PTR(conf_tgt); if (conf_tgt) { - strncpy(conf_tgt->sct_name, name, sizeof(conf_tgt->sct_name)); + strlcpy(conf_tgt->sct_name, name, sizeof(conf_tgt->sct_name)); sptlrpc_rule_set_init(&conf_tgt->sct_rset); - cfs_list_add(&conf_tgt->sct_list, &conf->sc_tgts); + list_add(&conf_tgt->sct_list, &conf->sc_tgts); } return conf_tgt; @@ -607,7 +605,7 @@ struct sptlrpc_conf *sptlrpc_conf_get(const char *fsname, { struct sptlrpc_conf *conf; - cfs_list_for_each_entry(conf, &sptlrpc_confs, sc_list) { + list_for_each_entry(conf, &sptlrpc_confs, sc_list) { if (strcmp(conf->sc_fsname, fsname) == 0) return conf; } @@ -619,10 +617,14 @@ struct sptlrpc_conf *sptlrpc_conf_get(const char *fsname, if (conf == NULL) return NULL; - strcpy(conf->sc_fsname, fsname); + if (strlcpy(conf->sc_fsname, fsname, sizeof(conf->sc_fsname)) >= + sizeof(conf->sc_fsname)) { + OBD_FREE_PTR(conf); + return NULL; + } sptlrpc_rule_set_init(&conf->sc_rset); - CFS_INIT_LIST_HEAD(&conf->sc_tgts); - cfs_list_add(&conf->sc_list, &sptlrpc_confs); + INIT_LIST_HEAD(&conf->sc_tgts); + list_add(&conf->sc_list, &sptlrpc_confs); CDEBUG(D_SEC, "create sptlrpc conf %s\n", conf->sc_fsname); return conf; @@ -694,9 +696,9 @@ static int __sptlrpc_process_config(struct lustre_cfg *lcfg, RETURN(-EINVAL); if (conf == NULL) { - target2fsname(target, fsname, sizeof(fsname)); + obdname2fsname(target, fsname, sizeof(fsname)); - cfs_mutex_lock(&sptlrpc_conf_lock); + mutex_lock(&sptlrpc_conf_lock); conf = sptlrpc_conf_get(fsname, 0); if (conf == NULL) { CERROR("can't find conf\n"); @@ -704,9 +706,9 @@ static int __sptlrpc_process_config(struct lustre_cfg *lcfg, } else { rc = sptlrpc_conf_merge_rule(conf, target, &rule); } - cfs_mutex_unlock(&sptlrpc_conf_lock); + mutex_unlock(&sptlrpc_conf_lock); } else { - LASSERT(cfs_mutex_is_locked(&sptlrpc_conf_lock)); + LASSERT(mutex_is_locked(&sptlrpc_conf_lock)); rc = sptlrpc_conf_merge_rule(conf, target, &rule); } @@ -748,16 +750,18 @@ void sptlrpc_conf_log_update_begin(const char *logname) if (logname2fsname(logname, fsname, sizeof(fsname))) return; - cfs_mutex_lock(&sptlrpc_conf_lock); + mutex_lock(&sptlrpc_conf_lock); conf = sptlrpc_conf_get(fsname, 0); - if (conf && conf->sc_local) { - LASSERT(conf->sc_updated == 0); - sptlrpc_conf_free_rsets(conf); - } - conf->sc_modified = 0; + if (conf) { + if (conf->sc_local) { + LASSERT(conf->sc_updated == 0); + sptlrpc_conf_free_rsets(conf); + } + conf->sc_modified = 0; + } - cfs_mutex_unlock(&sptlrpc_conf_lock); + mutex_unlock(&sptlrpc_conf_lock); } EXPORT_SYMBOL(sptlrpc_conf_log_update_begin); @@ -772,7 +776,7 @@ void sptlrpc_conf_log_update_end(const char *logname) if (logname2fsname(logname, fsname, sizeof(fsname))) return; - cfs_mutex_lock(&sptlrpc_conf_lock); + mutex_lock(&sptlrpc_conf_lock); conf = sptlrpc_conf_get(fsname, 0); if (conf) { @@ -786,7 +790,7 @@ void sptlrpc_conf_log_update_end(const char *logname) conf->sc_updated = 1; } - cfs_mutex_unlock(&sptlrpc_conf_lock); + mutex_unlock(&sptlrpc_conf_lock); } EXPORT_SYMBOL(sptlrpc_conf_log_update_end); @@ -797,9 +801,9 @@ void sptlrpc_conf_log_start(const char *logname) if (logname2fsname(logname, fsname, sizeof(fsname))) return; - cfs_mutex_lock(&sptlrpc_conf_lock); + mutex_lock(&sptlrpc_conf_lock); sptlrpc_conf_get(fsname, 1); - cfs_mutex_unlock(&sptlrpc_conf_lock); + mutex_unlock(&sptlrpc_conf_lock); } EXPORT_SYMBOL(sptlrpc_conf_log_start); @@ -811,11 +815,11 @@ void sptlrpc_conf_log_stop(const char *logname) if (logname2fsname(logname, fsname, sizeof(fsname))) return; - cfs_mutex_lock(&sptlrpc_conf_lock); + mutex_lock(&sptlrpc_conf_lock); conf = sptlrpc_conf_get(fsname, 0); if (conf) sptlrpc_conf_free(conf); - cfs_mutex_unlock(&sptlrpc_conf_lock); + mutex_unlock(&sptlrpc_conf_lock); } EXPORT_SYMBOL(sptlrpc_conf_log_stop); @@ -842,6 +846,14 @@ static void inline flavor_set_flags(struct sptlrpc_flavor *sf, if (fl_udesc && sf->sf_rpc != SPTLRPC_FLVR_NULL) sf->sf_flags |= PTLRPC_SEC_FL_UDESC; } + + /* Some flavors use a single uid (0) context */ + if (flvr_is_rootonly(sf->sf_rpc)) + sf->sf_flags |= PTLRPC_SEC_FL_ROOTONLY; + + /* User descriptor might need to be cleared */ + if (flvr_allows_user_desc(sf->sf_rpc) == 0) + sf->sf_flags &= ~PTLRPC_SEC_FL_UDESC; } void sptlrpc_conf_choose_flavor(enum lustre_sec_part from, @@ -855,9 +867,9 @@ void sptlrpc_conf_choose_flavor(enum lustre_sec_part from, char name[MTI_NAME_MAXLEN]; int len, rc = 0; - target2fsname(target->uuid, name, sizeof(name)); + obd_uuid2fsname(name, target->uuid, sizeof(name)); - cfs_mutex_lock(&sptlrpc_conf_lock); + mutex_lock(&sptlrpc_conf_lock); conf = sptlrpc_conf_get(name, 0); if (conf == NULL) @@ -879,7 +891,7 @@ void sptlrpc_conf_choose_flavor(enum lustre_sec_part from, rc = sptlrpc_rule_set_choose(&conf->sc_rset, from, to, nid, sf); out: - cfs_mutex_unlock(&sptlrpc_conf_lock); + mutex_unlock(&sptlrpc_conf_lock); if (rc == 0) get_default_flavor(sf); @@ -899,7 +911,6 @@ void sptlrpc_target_choose_flavor(struct sptlrpc_rule_set *rset, if (sptlrpc_rule_set_choose(rset, from, LUSTRE_SP_ANY, nid, sf) == 0) get_default_flavor(sf); } -EXPORT_SYMBOL(sptlrpc_target_choose_flavor); #define SEC_ADAPT_DELAY (10) @@ -912,343 +923,86 @@ void sptlrpc_conf_client_adapt(struct obd_device *obd) struct obd_import *imp; ENTRY; - LASSERT(strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 || - strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) ==0); - CDEBUG(D_SEC, "obd %s\n", obd->u.cli.cl_target_uuid.uuid); + LASSERT(strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) == 0 || + strcmp(obd->obd_type->typ_name, LUSTRE_OSC_NAME) == 0 || + strcmp(obd->obd_type->typ_name, LUSTRE_OSP_NAME) == 0 || + strcmp(obd->obd_type->typ_name, LUSTRE_LWP_NAME) == 0); + CDEBUG(D_SEC, "obd %s\n", obd->u.cli.cl_target_uuid.uuid); - /* serialize with connect/disconnect import */ - cfs_down_read(&obd->u.cli.cl_sem); + /* serialize with connect/disconnect import */ + down_read_nested(&obd->u.cli.cl_sem, OBD_CLI_SEM_MDCOSC); - imp = obd->u.cli.cl_import; - if (imp) { - cfs_spin_lock(&imp->imp_lock); - if (imp->imp_sec) - imp->imp_sec_expire = cfs_time_current_sec() + - SEC_ADAPT_DELAY; - cfs_spin_unlock(&imp->imp_lock); - } + imp = obd->u.cli.cl_import; + if (imp) { + spin_lock(&imp->imp_lock); + if (imp->imp_sec) + imp->imp_sec_expire = ktime_get_real_seconds() + + SEC_ADAPT_DELAY; + spin_unlock(&imp->imp_lock); + } - cfs_up_read(&obd->u.cli.cl_sem); - EXIT; + up_read(&obd->u.cli.cl_sem); + EXIT; } EXPORT_SYMBOL(sptlrpc_conf_client_adapt); -#ifdef __KERNEL__ - -static void rule2string(struct sptlrpc_rule *r, char *buf, int buflen) -{ - char dirbuf[8]; - char *net; - char *ptr = buf; - - if (r->sr_netid == LNET_NIDNET(LNET_NID_ANY)) - net = "default"; - else - net = libcfs_net2str(r->sr_netid); - - if (r->sr_from == LUSTRE_SP_ANY && r->sr_to == LUSTRE_SP_ANY) - dirbuf[0] = '\0'; - else - snprintf(dirbuf, sizeof(dirbuf), ".%s2%s", - sptlrpc_part2name(r->sr_from), - sptlrpc_part2name(r->sr_to)); - - ptr += snprintf(buf, buflen, "srpc.flavor.%s%s=", net, dirbuf); - - sptlrpc_flavor2name(&r->sr_flvr, ptr, buflen - (ptr - buf)); - buf[buflen - 1] = '\0'; -} - -static int sptlrpc_record_rule_set(struct llog_handle *llh, - char *target, - struct sptlrpc_rule_set *rset) -{ - struct lustre_cfg_bufs bufs; - struct lustre_cfg *lcfg; - struct llog_rec_hdr rec; - int buflen; - char param[48]; - int i, rc; - - for (i = 0; i < rset->srs_nrule; i++) { - rule2string(&rset->srs_rules[i], param, sizeof(param)); - - lustre_cfg_bufs_reset(&bufs, NULL); - lustre_cfg_bufs_set_string(&bufs, 1, target); - lustre_cfg_bufs_set_string(&bufs, 2, param); - lcfg = lustre_cfg_new(LCFG_SPTLRPC_CONF, &bufs); - LASSERT(lcfg); - - buflen = lustre_cfg_len(lcfg->lcfg_bufcount, - lcfg->lcfg_buflens); - rec.lrh_len = llog_data_len(buflen); - rec.lrh_type = OBD_CFG_REC; - rc = llog_write_rec(NULL, llh, &rec, NULL, 0, (void *)lcfg, -1); - if (rc) - CERROR("failed to write a rec: rc = %d\n", rc); - lustre_cfg_free(lcfg); - } - return 0; -} - -static int sptlrpc_record_rules(struct llog_handle *llh, - struct sptlrpc_conf *conf) -{ - struct sptlrpc_conf_tgt *conf_tgt; - - sptlrpc_record_rule_set(llh, conf->sc_fsname, &conf->sc_rset); - - cfs_list_for_each_entry(conf_tgt, &conf->sc_tgts, sct_list) { - sptlrpc_record_rule_set(llh, conf_tgt->sct_name, - &conf_tgt->sct_rset); - } - return 0; -} - -#define LOG_SPTLRPC_TMP "sptlrpc.tmp" -#define LOG_SPTLRPC "sptlrpc" - -static -int sptlrpc_target_local_copy_conf(struct obd_device *obd, - struct sptlrpc_conf *conf) -{ - struct llog_handle *llh = NULL; - struct llog_ctxt *ctxt; - struct lvfs_run_ctxt saved; - struct dentry *dentry; - int rc; - ENTRY; - - ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); - if (ctxt == NULL) { - CERROR("missing llog context\n"); - RETURN(-EINVAL); - } - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - dentry = ll_lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs), - strlen(MOUNT_CONFIGS_DIR)); - if (IS_ERR(dentry)) { - rc = PTR_ERR(dentry); - CERROR("cannot lookup %s directory: rc = %d\n", - MOUNT_CONFIGS_DIR, rc); - GOTO(out_ctx, rc); - } - - /* erase the old tmp log */ - rc = llog_create(NULL, ctxt, &llh, NULL, LOG_SPTLRPC_TMP); - if (rc == 0) { - rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL); - if (rc == 0) { - rc = llog_destroy(NULL, llh); - llog_free_handle(llh); - } else { - llog_close(NULL, llh); - } - } - - if (rc) { - CERROR("target %s: cannot erase temporary sptlrpc log: " - "rc = %d\n", obd->obd_name, rc); - GOTO(out_dput, rc); - } - - /* write temporary log */ - rc = llog_create(NULL, ctxt, &llh, NULL, LOG_SPTLRPC_TMP); - if (rc) - GOTO(out_dput, rc); - rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL); - if (rc) - GOTO(out_close, rc); - - rc = sptlrpc_record_rules(llh, conf); - -out_close: - llog_close(NULL, llh); - - if (rc == 0) { - rc = lustre_rename(dentry, obd->obd_lvfs_ctxt.pwdmnt, - LOG_SPTLRPC_TMP, LOG_SPTLRPC); - } - -out_dput: - l_dput(dentry); -out_ctx: - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - llog_ctxt_put(ctxt); - CDEBUG(D_SEC, "target %s: write local sptlrpc conf: rc = %d\n", - obd->obd_name, rc); - RETURN(rc); -} - -static int local_read_handler(const struct lu_env *env, - struct llog_handle *llh, - struct llog_rec_hdr *rec, void *data) -{ - struct sptlrpc_conf *conf = (struct sptlrpc_conf *) data; - struct lustre_cfg *lcfg = (struct lustre_cfg *)(rec + 1); - int cfg_len, rc; - ENTRY; - - if (rec->lrh_type != OBD_CFG_REC) { - CERROR("unhandled lrh_type: %#x\n", rec->lrh_type); - RETURN(-EINVAL); - } - - cfg_len = rec->lrh_len - sizeof(struct llog_rec_hdr) - - sizeof(struct llog_rec_tail); - - rc = lustre_cfg_sanity_check(lcfg, cfg_len); - if (rc) { - CERROR("Insane cfg\n"); - RETURN(rc); - } - - if (lcfg->lcfg_command != LCFG_SPTLRPC_CONF) { - CERROR("invalid command (%x)\n", lcfg->lcfg_command); - RETURN(-EINVAL); - } - - RETURN(__sptlrpc_process_config(lcfg, conf)); -} - -static -int sptlrpc_target_local_read_conf(struct obd_device *obd, - struct sptlrpc_conf *conf) -{ - struct llog_handle *llh = NULL; - struct llog_ctxt *ctxt; - struct lvfs_run_ctxt saved; - int rc; - ENTRY; - - LASSERT(conf->sc_updated == 0 && conf->sc_local == 0); - - ctxt = llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT); - if (ctxt == NULL) { - CERROR("missing llog context\n"); - RETURN(-EINVAL); - } - - push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - - rc = llog_create(NULL, ctxt, &llh, NULL, LOG_SPTLRPC); - if (rc) - GOTO(out_pop, rc); - - rc = llog_init_handle(NULL, llh, LLOG_F_IS_PLAIN, NULL); - if (rc) - GOTO(out_close, rc); - - if (llog_get_size(llh) <= 1) { - CDEBUG(D_SEC, "no local sptlrpc copy found\n"); - GOTO(out_close, rc = 0); - } - - rc = llog_process(NULL, llh, local_read_handler, (void *)conf, NULL); - - if (rc == 0) { - conf->sc_local = 1; - } else { - sptlrpc_conf_free_rsets(conf); - } - -out_close: - llog_close(NULL, llh); -out_pop: - pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); - llog_ctxt_put(ctxt); - CDEBUG(D_SEC, "target %s: read local sptlrpc conf: rc = %d\n", - obd->obd_name, rc); - RETURN(rc); -} - -#endif /* __KRENEL__ */ - /** * called by target devices, extract sptlrpc rules which applies to * this target, to be used for future rpc flavor checking. */ int sptlrpc_conf_target_get_rules(struct obd_device *obd, - struct sptlrpc_rule_set *rset, - int initial) -{ - struct sptlrpc_conf *conf; - struct sptlrpc_conf_tgt *conf_tgt; - enum lustre_sec_part sp_dst; - char fsname[MTI_NAME_MAXLEN]; - int rc = 0; - ENTRY; - - if (strcmp(obd->obd_type->typ_name, LUSTRE_MDT_NAME) == 0) { - sp_dst = LUSTRE_SP_MDT; - } else if (strcmp(obd->obd_type->typ_name, LUSTRE_OST_NAME) == 0) { - sp_dst = LUSTRE_SP_OST; - } else { - CERROR("unexpected obd type %s\n", obd->obd_type->typ_name); - RETURN(-EINVAL); - } - CDEBUG(D_SEC, "get rules for target %s\n", obd->obd_uuid.uuid); - - target2fsname(obd->obd_uuid.uuid, fsname, sizeof(fsname)); - - cfs_mutex_lock(&sptlrpc_conf_lock); - - conf = sptlrpc_conf_get(fsname, 0); - if (conf == NULL) { - CERROR("missing sptlrpc config log\n"); - GOTO(out, rc); - } - -#ifdef __KERNEL__ - if (conf->sc_updated == 0) { - /* - * always read from local copy. here another option is - * if we already have a local copy (read from another - * target device hosted on the same node) we simply use that. - */ - if (conf->sc_local) - sptlrpc_conf_free_rsets(conf); - - sptlrpc_target_local_read_conf(obd, conf); - } else { - LASSERT(conf->sc_local == 0); - - /* write a local copy */ - if (initial || conf->sc_modified) - sptlrpc_target_local_copy_conf(obd, conf); - else - CDEBUG(D_SEC, "unchanged, skip updating local copy\n"); - } -#endif - - /* extract rule set for this target */ - conf_tgt = sptlrpc_conf_get_tgt(conf, obd->obd_name, 0); - - rc = sptlrpc_rule_set_extract(&conf->sc_rset, - conf_tgt ? &conf_tgt->sct_rset: NULL, - LUSTRE_SP_ANY, sp_dst, rset); -out: - cfs_mutex_unlock(&sptlrpc_conf_lock); - RETURN(rc); + struct sptlrpc_rule_set *rset) +{ + struct sptlrpc_conf *conf; + struct sptlrpc_conf_tgt *conf_tgt; + enum lustre_sec_part sp_dst; + char fsname[MTI_NAME_MAXLEN]; + int rc = 0; + ENTRY; + + if (strcmp(obd->obd_type->typ_name, LUSTRE_MDT_NAME) == 0) { + sp_dst = LUSTRE_SP_MDT; + } else if (strcmp(obd->obd_type->typ_name, LUSTRE_OST_NAME) == 0) { + sp_dst = LUSTRE_SP_OST; + } else { + CERROR("unexpected obd type %s\n", obd->obd_type->typ_name); + RETURN(-EINVAL); + } + + obd_uuid2fsname(fsname, obd->obd_uuid.uuid, sizeof(fsname)); + + mutex_lock(&sptlrpc_conf_lock); + conf = sptlrpc_conf_get(fsname, 0); + if (conf == NULL) { + CERROR("missing sptlrpc config log\n"); + rc = -EFAULT; + } else { + /* extract rule set for this target */ + conf_tgt = sptlrpc_conf_get_tgt(conf, obd->obd_name, 0); + + rc = sptlrpc_rule_set_extract(&conf->sc_rset, + conf_tgt ? &conf_tgt->sct_rset : NULL, + LUSTRE_SP_ANY, sp_dst, rset); + } + mutex_unlock(&sptlrpc_conf_lock); + + RETURN(rc); } -EXPORT_SYMBOL(sptlrpc_conf_target_get_rules); int sptlrpc_conf_init(void) { - cfs_mutex_init(&sptlrpc_conf_lock); - return 0; + INIT_LIST_HEAD(&sptlrpc_confs); + mutex_init(&sptlrpc_conf_lock); + return 0; } void sptlrpc_conf_fini(void) { - struct sptlrpc_conf *conf, *conf_next; + struct sptlrpc_conf *conf, *conf_next; - cfs_mutex_lock(&sptlrpc_conf_lock); - cfs_list_for_each_entry_safe(conf, conf_next, &sptlrpc_confs, sc_list) { - sptlrpc_conf_free(conf); - } - LASSERT(cfs_list_empty(&sptlrpc_confs)); - cfs_mutex_unlock(&sptlrpc_conf_lock); + mutex_lock(&sptlrpc_conf_lock); + list_for_each_entry_safe(conf, conf_next, &sptlrpc_confs, sc_list) + sptlrpc_conf_free(conf); + LASSERT(list_empty(&sptlrpc_confs)); + mutex_unlock(&sptlrpc_conf_lock); }