* user supplied flavor string parsing *
****************************************/
-#ifdef HAVE_ADLER
-#define BULK_HASH_ALG_DEFAULT BULK_HASH_ALG_ADLER32
-#else
-#define BULK_HASH_ALG_DEFAULT BULK_HASH_ALG_CRC32
-#endif
-
-typedef enum {
- BULK_TYPE_N = 0,
- BULK_TYPE_I = 1,
- BULK_TYPE_P = 2
-} bulk_type_t;
-
-static void get_default_flavor(struct sptlrpc_flavor *sf)
-{
- sf->sf_rpc = SPTLRPC_FLVR_NULL;
- sf->sf_bulk_ciph = BULK_CIPH_ALG_NULL;
- sf->sf_bulk_hash = BULK_HASH_ALG_NULL;
- sf->sf_flags = 0;
-}
-
-static void get_flavor_by_rpc(struct sptlrpc_flavor *flvr, __u16 rpc_flavor)
-{
- get_default_flavor(flvr);
-
- flvr->sf_rpc = rpc_flavor;
-
- switch (rpc_flavor) {
- case SPTLRPC_FLVR_NULL:
- break;
- case SPTLRPC_FLVR_PLAIN:
- case SPTLRPC_FLVR_KRB5N:
- case SPTLRPC_FLVR_KRB5A:
- flvr->sf_bulk_hash = BULK_HASH_ALG_DEFAULT;
- break;
- case SPTLRPC_FLVR_KRB5P:
- flvr->sf_bulk_ciph = BULK_CIPH_ALG_AES128;
- /* fall through */
- case SPTLRPC_FLVR_KRB5I:
- flvr->sf_bulk_hash = BULK_HASH_ALG_SHA1;
- break;
- default:
- LBUG();
- }
-}
-
-static void get_flavor_by_bulk(struct sptlrpc_flavor *flvr,
- __u16 rpc_flavor, bulk_type_t bulk_type)
-{
- switch (bulk_type) {
- case BULK_TYPE_N:
- flvr->sf_bulk_hash = BULK_HASH_ALG_NULL;
- flvr->sf_bulk_ciph = BULK_CIPH_ALG_NULL;
- break;
- case BULK_TYPE_I:
- switch (rpc_flavor) {
- case SPTLRPC_FLVR_PLAIN:
- case SPTLRPC_FLVR_KRB5N:
- case SPTLRPC_FLVR_KRB5A:
- flvr->sf_bulk_hash = BULK_HASH_ALG_DEFAULT;
- break;
- case SPTLRPC_FLVR_KRB5I:
- case SPTLRPC_FLVR_KRB5P:
- flvr->sf_bulk_hash = BULK_HASH_ALG_SHA1;
- break;
- default:
- LBUG();
- }
- flvr->sf_bulk_ciph = BULK_CIPH_ALG_NULL;
- break;
- case BULK_TYPE_P:
- flvr->sf_bulk_hash = BULK_HASH_ALG_SHA1;
- flvr->sf_bulk_ciph = BULK_CIPH_ALG_AES128;
- break;
- default:
- LBUG();
- }
-}
-
-static __u16 __flavors[] = {
- SPTLRPC_FLVR_NULL,
- SPTLRPC_FLVR_PLAIN,
- SPTLRPC_FLVR_KRB5N,
- SPTLRPC_FLVR_KRB5A,
- SPTLRPC_FLVR_KRB5I,
- SPTLRPC_FLVR_KRB5P,
-};
-
-#define __nflavors ARRAY_SIZE(__flavors)
-
/*
- * flavor string format: rpc[-bulk{n|i|p}[:cksum/enc]]
- * for examples:
- * null
- * plain-bulki
- * krb5p-bulkn
- * krb5i-bulkp
- * krb5i-bulkp:sha512/arc4
+ * format: <base_flavor>[-<bulk_type:alg_spec>]
*/
-static int parse_flavor(const char *str, struct sptlrpc_flavor *flvr)
+int sptlrpc_parse_flavor(const char *str, struct sptlrpc_flavor *flvr)
{
- const char *f;
- char *bulk, *alg, *enc;
- char buf[64];
- bulk_type_t bulk_type;
- __u8 i;
- ENTRY;
+ char buf[32];
+ char *bulk, *alg;
+
+ memset(flvr, 0, sizeof(*flvr));
if (str == NULL || str[0] == '\0') {
flvr->sf_rpc = SPTLRPC_FLVR_INVALID;
- goto out;
+ return 0;
}
- for (i = 0; i < __nflavors; i++) {
- f = sptlrpc_rpcflavor2name(__flavors[i]);
- if (strncmp(str, f, strlen(f)) == 0)
- break;
- }
-
- if (i >= __nflavors)
- GOTO(invalid, -EINVAL);
+ strncpy(buf, str, sizeof(buf));
+ buf[sizeof(buf) - 1] = '\0';
- /* prepare local buffer thus we can modify it as we want */
- strncpy(buf, str, 64);
- buf[64 - 1] = '\0';
-
- /* find bulk string */
bulk = strchr(buf, '-');
if (bulk)
*bulk++ = '\0';
- /* now the first part must equal to rpc flavor name */
- if (strcmp(buf, f) != 0)
- GOTO(invalid, -EINVAL);
-
- get_flavor_by_rpc(flvr, __flavors[i]);
-
- if (bulk == NULL)
- goto out;
-
- /* find bulk algorithm string */
- alg = strchr(bulk, ':');
- if (alg)
- *alg++ = '\0';
-
- /* verify bulk section */
- if (strcmp(bulk, "bulkn") == 0) {
- flvr->sf_bulk_hash = BULK_HASH_ALG_NULL;
- flvr->sf_bulk_ciph = BULK_CIPH_ALG_NULL;
- bulk_type = BULK_TYPE_N;
- } else if (strcmp(bulk, "bulki") == 0)
- bulk_type = BULK_TYPE_I;
- else if (strcmp(bulk, "bulkp") == 0)
- bulk_type = BULK_TYPE_P;
- else
- GOTO(invalid, -EINVAL);
-
- /* null flavor don't support bulk i/p */
- if (__flavors[i] == SPTLRPC_FLVR_NULL && bulk_type != BULK_TYPE_N)
- GOTO(invalid, -EINVAL);
-
- /* plain policy dosen't support bulk p */
- if (__flavors[i] == SPTLRPC_FLVR_PLAIN && bulk_type == BULK_TYPE_P)
- GOTO(invalid, -EINVAL);
-
- get_flavor_by_bulk(flvr, __flavors[i], bulk_type);
-
- if (alg == NULL)
- goto out;
-
- /* find encryption algorithm string */
- enc = strchr(alg, '/');
- if (enc)
- *enc++ = '\0';
-
- /* checksum algorithm */
- for (i = 0; i < BULK_HASH_ALG_MAX; i++) {
- if (strcmp(alg, sptlrpc_get_hash_name(i)) == 0) {
- flvr->sf_bulk_hash = i;
- break;
- }
- }
- if (i >= BULK_HASH_ALG_MAX)
- GOTO(invalid, -EINVAL);
-
- /* privacy algorithm */
- if (enc) {
- for (i = 0; i < BULK_CIPH_ALG_MAX; i++) {
- if (strcmp(enc, sptlrpc_get_ciph_name(i)) == 0) {
- flvr->sf_bulk_ciph = i;
- break;
- }
- }
- if (i >= BULK_CIPH_ALG_MAX)
- GOTO(invalid, -EINVAL);
- }
+ flvr->sf_rpc = sptlrpc_name2flavor_base(buf);
+ if (flvr->sf_rpc == SPTLRPC_FLVR_INVALID)
+ goto err_out;
/*
- * bulk combination sanity checks
+ * currently only base flavor "plain" can have bulk specification.
*/
- if (bulk_type == BULK_TYPE_P &&
- flvr->sf_bulk_ciph == BULK_CIPH_ALG_NULL)
- GOTO(invalid, -EINVAL);
-
- if (bulk_type == BULK_TYPE_I &&
- (flvr->sf_bulk_hash == BULK_HASH_ALG_NULL ||
- flvr->sf_bulk_ciph != BULK_CIPH_ALG_NULL))
- GOTO(invalid, -EINVAL);
+ if (flvr->sf_rpc == SPTLRPC_FLVR_PLAIN) {
+ flvr->u_bulk.hash.hash_alg = BULK_HASH_ALG_ADLER32;
+ if (bulk) {
+ /*
+ * format: plain-hash:<hash_alg>
+ */
+ alg = strchr(bulk, ':');
+ if (alg == NULL)
+ goto err_out;
+ *alg++ = '\0';
+
+ if (strcmp(bulk, "hash"))
+ goto err_out;
+
+ flvr->u_bulk.hash.hash_alg = sptlrpc_get_hash_alg(alg);
+ if (flvr->u_bulk.hash.hash_alg >= BULK_HASH_ALG_MAX)
+ goto err_out;
+ }
- if (bulk_type == BULK_TYPE_N &&
- (flvr->sf_bulk_hash != BULK_HASH_ALG_NULL ||
- flvr->sf_bulk_ciph != BULK_CIPH_ALG_NULL))
- GOTO(invalid, -EINVAL);
+ if (flvr->u_bulk.hash.hash_alg == BULK_HASH_ALG_NULL)
+ flvr_set_bulk_svc(&flvr->sf_rpc, SPTLRPC_BULK_SVC_NULL);
+ else
+ flvr_set_bulk_svc(&flvr->sf_rpc, SPTLRPC_BULK_SVC_INTG);
+ } else {
+ if (bulk)
+ goto err_out;
+ }
-out:
+ flvr->sf_flags = 0;
return 0;
-invalid:
+
+err_out:
CERROR("invalid flavor string: %s\n", str);
return -EINVAL;
}
+EXPORT_SYMBOL(sptlrpc_parse_flavor);
/****************************************
* configure rules *
****************************************/
+static void get_default_flavor(struct sptlrpc_flavor *sf)
+{
+ memset(sf, 0, sizeof(*sf));
+
+ sf->sf_rpc = SPTLRPC_FLVR_NULL;
+ sf->sf_flags = 0;
+}
+
static void sptlrpc_rule_init(struct sptlrpc_rule *rule)
{
rule->sr_netid = LNET_NIDNET(LNET_NID_ANY);
}
/* 2.1 flavor */
- rc = parse_flavor(flavor, &rule->sr_flvr);
+ rc = sptlrpc_parse_flavor(flavor, &rule->sr_flvr);
if (rc)
RETURN(-EINVAL);
/*
* return 0 if the rule set could accomodate one more rule.
- * if @expand != 0, the rule set might be expanded.
*/
-int sptlrpc_rule_set_expand(struct sptlrpc_rule_set *rset, int expand)
+int sptlrpc_rule_set_expand(struct sptlrpc_rule_set *rset)
{
struct sptlrpc_rule *rules;
int nslot;
+ cfs_might_sleep();
+
if (rset->srs_nrule < rset->srs_nslot)
return 0;
- if (expand == 0)
- return -E2BIG;
-
nslot = rset->srs_nslot + 8;
/* better use realloc() if available */
/*
* merge @rule into @rset.
- * if @expand != 0 then @rset slots might be expanded.
+ * the @rset slots might be expanded.
*/
int sptlrpc_rule_set_merge(struct sptlrpc_rule_set *rset,
- struct sptlrpc_rule *rule,
- int expand)
+ struct sptlrpc_rule *rule)
{
struct sptlrpc_rule *p = rset->srs_rules;
int spec_dir, spec_net;
int rc, n, match = 0;
+ cfs_might_sleep();
+
spec_net = rule_spec_net(rule);
spec_dir = rule_spec_dir(rule);
LASSERT(n >= 0 && n <= rset->srs_nrule);
if (rule->sr_flvr.sf_rpc != SPTLRPC_FLVR_INVALID) {
- rc = sptlrpc_rule_set_expand(rset, expand);
+ rc = sptlrpc_rule_set_expand(rset);
if (rc)
return rc;
* given from/to/nid, determine a matching flavor in ruleset.
* return 1 if a match found, otherwise return 0.
*/
-static int sptlrpc_rule_set_choose(struct sptlrpc_rule_set *rset,
- enum lustre_sec_part from,
- enum lustre_sec_part to,
- lnet_nid_t nid,
- struct sptlrpc_flavor *sf)
+int sptlrpc_rule_set_choose(struct sptlrpc_rule_set *rset,
+ enum lustre_sec_part from,
+ enum lustre_sec_part to,
+ lnet_nid_t nid,
+ struct sptlrpc_flavor *sf)
{
struct sptlrpc_rule *r;
int n;
return 0;
}
+EXPORT_SYMBOL(sptlrpc_rule_set_choose);
void sptlrpc_rule_set_dump(struct sptlrpc_rule_set *rset)
{
struct sptlrpc_rule *rule;
int i, n, rc;
+ cfs_might_sleep();
+
/* merge general rules firstly, then target-specific rules */
for (i = 0; i < 2; i++) {
if (src[i] == NULL)
rule->sr_to != to)
continue;
- rc = sptlrpc_rule_set_merge(rset, rule, 1);
+ rc = sptlrpc_rule_set_merge(rset, rule);
if (rc) {
CERROR("can't merge: %d\n", rc);
return rc;
**********************************/
struct sptlrpc_conf_tgt {
- struct list_head sct_list;
+ cfs_list_t sct_list;
char sct_name[MAX_OBD_NAME];
struct sptlrpc_rule_set sct_rset;
};
struct sptlrpc_conf {
- struct list_head sc_list;
+ 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 */
- struct list_head sc_tgts; /* target-specific rules */
+ cfs_list_t sc_tgts; /* target-specific rules */
};
-static struct mutex sptlrpc_conf_lock;
+static cfs_mutex_t sptlrpc_conf_lock;
static CFS_LIST_HEAD(sptlrpc_confs);
static inline int is_hex(char c)
sptlrpc_rule_set_free(&conf->sc_rset);
- list_for_each_entry_safe(conf_tgt, conf_tgt_next,
- &conf->sc_tgts, sct_list) {
+ cfs_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);
+ cfs_list_del(&conf_tgt->sct_list);
OBD_FREE_PTR(conf_tgt);
}
- LASSERT(list_empty(&conf->sc_tgts));
+ LASSERT(cfs_list_empty(&conf->sc_tgts));
conf->sc_updated = 0;
conf->sc_local = 0;
CDEBUG(D_SEC, "free sptlrpc conf %s\n", conf->sc_fsname);
sptlrpc_conf_free_rsets(conf);
- list_del(&conf->sc_list);
+ cfs_list_del(&conf->sc_list);
OBD_FREE_PTR(conf);
}
{
struct sptlrpc_conf_tgt *conf_tgt;
- list_for_each_entry(conf_tgt, &conf->sc_tgts, sct_list) {
+ cfs_list_for_each_entry(conf_tgt, &conf->sc_tgts, sct_list) {
if (strcmp(conf_tgt->sct_name, name) == 0)
return conf_tgt;
}
if (conf_tgt) {
strncpy(conf_tgt->sct_name, name, sizeof(conf_tgt->sct_name));
sptlrpc_rule_set_init(&conf_tgt->sct_rset);
- list_add(&conf_tgt->sct_list, &conf->sc_tgts);
+ cfs_list_add(&conf_tgt->sct_list, &conf->sc_tgts);
}
return conf_tgt;
{
struct sptlrpc_conf *conf;
- list_for_each_entry(conf, &sptlrpc_confs, sc_list) {
+ cfs_list_for_each_entry(conf, &sptlrpc_confs, sc_list) {
if (strcmp(conf->sc_fsname, fsname) == 0)
return conf;
}
strcpy(conf->sc_fsname, fsname);
sptlrpc_rule_set_init(&conf->sc_rset);
CFS_INIT_LIST_HEAD(&conf->sc_tgts);
- list_add(&conf->sc_list, &sptlrpc_confs);
+ cfs_list_add(&conf->sc_list, &sptlrpc_confs);
CDEBUG(D_SEC, "create sptlrpc conf %s\n", conf->sc_fsname);
return conf;
}
}
- return sptlrpc_rule_set_merge(rule_set, rule, 1);
+ return sptlrpc_rule_set_merge(rule_set, rule);
}
/**
RETURN(-EINVAL);
}
+ CDEBUG(D_SEC, "processing rule: %s.%s\n", target, param);
+
/* parse rule to make sure the format is correct */
if (strncmp(param, PARAM_SRPC_FLVR, sizeof(PARAM_SRPC_FLVR) - 1) != 0) {
CERROR("Invalid sptlrpc parameter: %s\n", param);
if (conf == NULL) {
target2fsname(target, fsname, sizeof(fsname));
- mutex_lock(&sptlrpc_conf_lock);
+ cfs_mutex_lock(&sptlrpc_conf_lock);
conf = sptlrpc_conf_get(fsname, 0);
if (conf == NULL) {
CERROR("can't find conf\n");
} else {
rc = sptlrpc_conf_merge_rule(conf, target, &rule);
}
- mutex_unlock(&sptlrpc_conf_lock);
+ cfs_mutex_unlock(&sptlrpc_conf_lock);
} else {
- LASSERT(mutex_is_locked(&sptlrpc_conf_lock));
+ LASSERT(cfs_mutex_is_locked(&sptlrpc_conf_lock));
rc = sptlrpc_conf_merge_rule(conf, target, &rule);
}
if (logname2fsname(logname, fsname, sizeof(fsname)))
return;
- mutex_lock(&sptlrpc_conf_lock);
+ cfs_mutex_lock(&sptlrpc_conf_lock);
conf = sptlrpc_conf_get(fsname, 0);
if (conf && conf->sc_local) {
}
conf->sc_modified = 0;
- mutex_unlock(&sptlrpc_conf_lock);
+ cfs_mutex_unlock(&sptlrpc_conf_lock);
}
EXPORT_SYMBOL(sptlrpc_conf_log_update_begin);
if (logname2fsname(logname, fsname, sizeof(fsname)))
return;
- mutex_lock(&sptlrpc_conf_lock);
+ cfs_mutex_lock(&sptlrpc_conf_lock);
conf = sptlrpc_conf_get(fsname, 0);
if (conf) {
conf->sc_updated = 1;
}
- mutex_unlock(&sptlrpc_conf_lock);
+ cfs_mutex_unlock(&sptlrpc_conf_lock);
}
EXPORT_SYMBOL(sptlrpc_conf_log_update_end);
if (logname2fsname(logname, fsname, sizeof(fsname)))
return;
- mutex_lock(&sptlrpc_conf_lock);
+ cfs_mutex_lock(&sptlrpc_conf_lock);
conf = sptlrpc_conf_get(fsname, 1);
- mutex_unlock(&sptlrpc_conf_lock);
+ cfs_mutex_unlock(&sptlrpc_conf_lock);
}
EXPORT_SYMBOL(sptlrpc_conf_log_start);
if (logname2fsname(logname, fsname, sizeof(fsname)))
return;
- mutex_lock(&sptlrpc_conf_lock);
+ cfs_mutex_lock(&sptlrpc_conf_lock);
conf = sptlrpc_conf_get(fsname, 0);
if (conf)
sptlrpc_conf_free(conf);
- mutex_unlock(&sptlrpc_conf_lock);
+ cfs_mutex_unlock(&sptlrpc_conf_lock);
}
EXPORT_SYMBOL(sptlrpc_conf_log_stop);
enum lustre_sec_part to,
unsigned int fl_udesc)
{
+ /*
+ * null flavor doesn't need to set any flavor, and in fact
+ * we'd better not do that because everybody share a single sec.
+ */
+ if (sf->sf_rpc == SPTLRPC_FLVR_NULL)
+ return;
+
if (from == LUSTRE_SP_MDT) {
/* MDT->MDT; MDT->OST */
sf->sf_flags |= PTLRPC_SEC_FL_ROOTONLY;
target2fsname(target->uuid, name, sizeof(name));
- mutex_lock(&sptlrpc_conf_lock);
+ cfs_mutex_lock(&sptlrpc_conf_lock);
conf = sptlrpc_conf_get(name, 0);
if (conf == NULL)
rc = sptlrpc_rule_set_choose(&conf->sc_rset, from, to, nid, sf);
out:
- mutex_unlock(&sptlrpc_conf_lock);
+ cfs_mutex_unlock(&sptlrpc_conf_lock);
if (rc == 0)
get_default_flavor(sf);
CDEBUG(D_SEC, "obd %s\n", obd->u.cli.cl_target_uuid.uuid);
/* serialize with connect/disconnect import */
- down_read(&obd->u.cli.cl_sem);
+ cfs_down_read(&obd->u.cli.cl_sem);
imp = obd->u.cli.cl_import;
if (imp) {
- spin_lock(&imp->imp_lock);
+ cfs_spin_lock(&imp->imp_lock);
if (imp->imp_sec)
imp->imp_sec_expire = cfs_time_current_sec() +
SEC_ADAPT_DELAY;
- spin_unlock(&imp->imp_lock);
+ cfs_spin_unlock(&imp->imp_lock);
}
- up_read(&obd->u.cli.cl_sem);
+ cfs_up_read(&obd->u.cli.cl_sem);
EXIT;
}
EXPORT_SYMBOL(sptlrpc_conf_client_adapt);
sptlrpc_record_rule_set(llh, conf->sc_fsname, &conf->sc_rset);
- list_for_each_entry(conf_tgt, &conf->sc_tgts, sct_list) {
+ 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);
}
push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- dentry = lookup_one_len(MOUNT_CONFIGS_DIR, current->fs->pwd,
+ dentry = lookup_one_len(MOUNT_CONFIGS_DIR, cfs_fs_pwd(current->fs),
strlen(MOUNT_CONFIGS_DIR));
if (IS_ERR(dentry)) {
rc = PTR_ERR(dentry);
target2fsname(obd->obd_uuid.uuid, fsname, sizeof(fsname));
- mutex_lock(&sptlrpc_conf_lock);
+ cfs_mutex_lock(&sptlrpc_conf_lock);
conf = sptlrpc_conf_get(fsname, 0);
if (conf == NULL) {
conf_tgt ? &conf_tgt->sct_rset: NULL,
LUSTRE_SP_ANY, sp_dst, rset);
out:
- mutex_unlock(&sptlrpc_conf_lock);
+ cfs_mutex_unlock(&sptlrpc_conf_lock);
RETURN(rc);
}
EXPORT_SYMBOL(sptlrpc_conf_target_get_rules);
int sptlrpc_conf_init(void)
{
- mutex_init(&sptlrpc_conf_lock);
+ cfs_mutex_init(&sptlrpc_conf_lock);
return 0;
}
{
struct sptlrpc_conf *conf, *conf_next;
- mutex_lock(&sptlrpc_conf_lock);
- list_for_each_entry_safe(conf, conf_next, &sptlrpc_confs, sc_list) {
+ cfs_mutex_lock(&sptlrpc_conf_lock);
+ cfs_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);
+ LASSERT(cfs_list_empty(&sptlrpc_confs));
+ cfs_mutex_unlock(&sptlrpc_conf_lock);
}