char sid_val[0];
};
+#define RSC_DOWNCALL_MAGIC 0x6d6dd62b
+#define RSC_DOWNCALL_PATH "sptlrpc/gss/rsc_info"
+#define RSC_CACHE_NAME "rsccache"
+
+/* rsc_downcall_data flags */
+enum scd_flag_bits {
+ RSC_DATA_FLAG_REMOTE = 0x0001,
+ RSC_DATA_FLAG_ROOT = 0x0002,
+ RSC_DATA_FLAG_MDS = 0x0004,
+ RSC_DATA_FLAG_OSS = 0x0008,
+};
+
+struct rsc_downcall_data {
+ __u32 scd_magic;
+ __u32 scd_err;
+ __u32 scd_flags;
+ __u32 scd_mapped_uid;
+ __u32 scd_uid;
+ __u32 scd_gid;
+ char scd_mechname[8];
+ __s64 scd_offset;
+ __u32 scd_len;
+ __u32 scd_padding;
+ /* scd_val contains handle and context token */
+ char scd_val[0];
+};
+
/*
* gss_string_write() - write some string
*
int si_minor_status;
};
+struct gss_rsc {
+ struct upcall_cache_entry *sc_uc_entry;
+ struct obd_device *sc_target;
+ rawobj_t sc_handle;
+ struct gss_svc_ctx sc_ctx;
+};
+
struct upcall_cache_entry {
struct list_head ue_hash;
uint64_t ue_key;
union {
struct md_identity identity;
struct gss_rsi rsi;
+ struct gss_rsc rsc;
} u;
};
#define RSI_UPCALL_PATH "/usr/sbin/l_getauth"
#define UC_RSICACHE_HASH_SIZE 64
-
extern struct upcall_cache_ops rsi_upcall_cache_ops;
extern struct upcall_cache *rsicache;
struct gss_rsi *rsi_entry_get(struct upcall_cache *cache, struct gss_rsi *rsi);
void rsi_entry_put(struct upcall_cache *cache, struct gss_rsi *rsi);
void rsi_flush(struct upcall_cache *cache, int hash);
+#define RSC_UPCALL_PATH "NONE"
+#define UC_RSCCACHE_HASH_SIZE 1024
+extern struct upcall_cache_ops rsc_upcall_cache_ops;
+extern struct upcall_cache *rsccache;
+struct gss_rsc *rsc_entry_get(struct upcall_cache *cache, struct gss_rsc *rsc);
+void rsc_entry_put(struct upcall_cache *cache, struct gss_rsc *rsc);
+void rsc_flush(struct upcall_cache *cache, int hash);
+void __rsc_free(struct gss_rsc *rsc);
#endif /* __PTLRPC_GSS_GSS_INTERNAL_H_ */
}
/****************************************
- * rpc sec context (rsc) cache *
+ * rpc sec context (rsc) cache *
****************************************/
#define RSC_HASHBITS (10)
#define RSC_HASHMAX (1 << RSC_HASHBITS)
#define RSC_HASHMASK (RSC_HASHMAX - 1)
+static void rsc_entry_init(struct upcall_cache_entry *entry,
+ void *args)
+{
+ struct gss_rsc *rsc = &entry->u.rsc;
+ struct gss_rsc *tmp = args;
+
+ rsc->sc_uc_entry = entry;
+ rawobj_dup(&rsc->sc_handle, &tmp->sc_handle);
+
+ rsc->sc_target = NULL;
+ memset(&rsc->sc_ctx, 0, sizeof(rsc->sc_ctx));
+ rsc->sc_ctx.gsc_rvs_hdl = RAWOBJ_EMPTY;
+
+ memset(&rsc->sc_ctx.gsc_seqdata, 0, sizeof(rsc->sc_ctx.gsc_seqdata));
+ spin_lock_init(&rsc->sc_ctx.gsc_seqdata.ssd_lock);
+}
+
+void __rsc_free(struct gss_rsc *rsc)
+{
+ rawobj_free(&rsc->sc_handle);
+ rawobj_free(&rsc->sc_ctx.gsc_rvs_hdl);
+ lgss_delete_sec_context(&rsc->sc_ctx.gsc_mechctx);
+}
+
+static void rsc_entry_free(struct upcall_cache *cache,
+ struct upcall_cache_entry *entry)
+{
+ struct gss_rsc *rsc = &entry->u.rsc;
+
+ __rsc_free(rsc);
+}
+
+static inline int rsc_entry_hash(struct gss_rsc *rsc)
+{
+#if BITS_PER_LONG == 64
+ return hash_mem_64((char *)rsc->sc_handle.data,
+ rsc->sc_handle.len, RSC_HASHBITS);
+#else
+ return hash_mem((char *)rsc->sc_handle.data,
+ rsc->sc_handle.len, RSC_HASHBITS);
+#endif
+}
+
+static inline int __rsc_entry_match(rawobj_t *h1, rawobj_t *h2)
+{
+ return !(rawobj_equal(h1, h2));
+}
+
+static inline int rsc_entry_match(struct gss_rsc *rsc, struct gss_rsc *tmp)
+{
+ return __rsc_entry_match(&rsc->sc_handle, &tmp->sc_handle);
+}
+
+/* Returns 0 to tell this is a match */
+static inline int rsc_upcall_compare(struct upcall_cache *cache,
+ struct upcall_cache_entry *entry,
+ __u64 key, void *args)
+{
+ struct gss_rsc *rsc1 = &entry->u.rsc;
+ struct gss_rsc *rsc2 = args;
+
+ return rsc_entry_match(rsc1, rsc2);
+}
+
+/* rsc upcall is a no-op, we just need a valid entry */
+static inline int rsc_do_upcall(struct upcall_cache *cache,
+ struct upcall_cache_entry *entry)
+{
+ upcall_cache_update_entry(cache, entry,
+ ktime_get_seconds() + cache->uc_entry_expire,
+ 0);
+ return 0;
+}
+
+static inline int rsc_downcall_compare(struct upcall_cache *cache,
+ struct upcall_cache_entry *entry,
+ __u64 key, void *args)
+{
+ struct gss_rsc *rsc = &entry->u.rsc;
+ struct rsc_downcall_data *scd = args;
+ char *mesg = scd->scd_val;
+ rawobj_t handle;
+ int len;
+
+ /* scd_val starts with handle */
+ len = gss_buffer_get(&mesg, &handle.len, &handle.data);
+ scd->scd_offset = mesg - scd->scd_val;
+
+ return __rsc_entry_match(&rsc->sc_handle, &handle);
+}
+
+static int rsc_parse_downcall(struct upcall_cache *cache,
+ struct upcall_cache_entry *entry,
+ void *args)
+{
+ struct gss_api_mech *gm = NULL;
+ struct gss_rsc *rsc = &entry->u.rsc;
+ struct rsc_downcall_data *scd = args;
+ int mlen = scd->scd_len;
+ char *mesg = scd->scd_val + scd->scd_offset;
+ char *buf = scd->scd_val;
+ int status = -EINVAL;
+ time64_t ctx_expiry;
+ rawobj_t tmp_buf;
+ int len;
+
+ ENTRY;
+
+ if (mlen <= 0)
+ goto out;
+
+ rsc->sc_ctx.gsc_remote = !!(scd->scd_flags & RSC_DATA_FLAG_REMOTE);
+ rsc->sc_ctx.gsc_usr_root = !!(scd->scd_flags & RSC_DATA_FLAG_ROOT);
+ rsc->sc_ctx.gsc_usr_mds = !!(scd->scd_flags & RSC_DATA_FLAG_MDS);
+ rsc->sc_ctx.gsc_usr_oss = !!(scd->scd_flags & RSC_DATA_FLAG_OSS);
+ rsc->sc_ctx.gsc_mapped_uid = scd->scd_mapped_uid;
+ rsc->sc_ctx.gsc_uid = scd->scd_uid;
+
+ rsc->sc_ctx.gsc_gid = scd->scd_gid;
+ gm = lgss_name_to_mech(scd->scd_mechname);
+ if (!gm) {
+ status = -EOPNOTSUPP;
+ goto out;
+ }
+
+ /* handle has already been consumed in rsc_downcall_compare().
+ * scd_offset gives next field.
+ */
+
+ /* context token */
+ len = gss_buffer_read(&mesg, buf, mlen);
+ if (len < 0)
+ goto out;
+ tmp_buf.len = len;
+ tmp_buf.data = (unsigned char *)buf;
+ if (lgss_import_sec_context(&tmp_buf, gm,
+ &rsc->sc_ctx.gsc_mechctx))
+ goto out;
+
+ if (lgss_inquire_context(rsc->sc_ctx.gsc_mechctx, &ctx_expiry))
+ goto out;
+
+ /* ctx_expiry is the number of seconds since Jan 1 1970.
+ * We just want the number of seconds into the future.
+ */
+ entry->ue_expire = ktime_get_seconds() +
+ (ctx_expiry - ktime_get_real_seconds());
+ status = 0;
+
+out:
+ if (gm)
+ lgss_mech_put(gm);
+ CDEBUG(D_OTHER, "rsc parse %p: %d\n", rsc, status);
+ RETURN(status);
+}
+
+struct gss_rsc *rsc_entry_get(struct upcall_cache *cache, struct gss_rsc *rsc)
+{
+ struct upcall_cache_entry *entry;
+ int hash = rsc_entry_hash(rsc);
+
+ if (!cache)
+ return ERR_PTR(-ENOENT);
+
+ entry = upcall_cache_get_entry(cache, (__u64)hash, rsc);
+ if (unlikely(!entry))
+ return ERR_PTR(-ENOENT);
+ if (IS_ERR(entry))
+ return ERR_CAST(entry);
+
+ return &entry->u.rsc;
+}
+
+void rsc_entry_put(struct upcall_cache *cache, struct gss_rsc *rsc)
+{
+ if (!cache || !rsc)
+ return;
+
+ upcall_cache_put_entry(cache, rsc->sc_uc_entry);
+}
+
+void rsc_flush(struct upcall_cache *cache, int hash)
+{
+ if (hash < 0)
+ upcall_cache_flush_idle(cache);
+ else
+ upcall_cache_flush_one(cache, (__u64)hash, NULL);
+}
+
+struct upcall_cache_ops rsc_upcall_cache_ops = {
+ .init_entry = rsc_entry_init,
+ .free_entry = rsc_entry_free,
+ .upcall_compare = rsc_upcall_compare,
+ .downcall_compare = rsc_downcall_compare,
+ .do_upcall = rsc_do_upcall,
+ .parse_downcall = rsc_parse_downcall,
+};
+
+struct upcall_cache *rsccache;
+
struct rsc {
struct cache_head h;
struct obd_device *target;
* rsc cache flush *
****************************************/
-static struct rsc *gss_svc_searchbyctx(rawobj_t *handle)
+static struct gss_rsc *gss_svc_searchbyctx(rawobj_t *handle)
{
- struct rsc rsci;
- struct rsc *found;
+ struct gss_rsc rsc;
+ struct gss_rsc *found;
- memset(&rsci, 0, sizeof(rsci));
- if (rawobj_dup(&rsci.handle, handle))
- return NULL;
+ memset(&rsc, 0, sizeof(rsc));
+ if (rawobj_dup(&rsc.sc_handle, handle))
+ return NULL;
- found = rsc_lookup(&rsci);
- rsc_free(&rsci);
- if (!found)
- return NULL;
- if (cache_check(&rsc_cache, &found->h, NULL))
- return NULL;
- return found;
+ found = rsc_entry_get(rsccache, &rsc);
+ __rsc_free(&rsc);
+ if (IS_ERR_OR_NULL(found))
+ return found;
+ if (!found->sc_ctx.gsc_mechctx) {
+ rsc_entry_put(rsccache, found);
+ return ERR_PTR(-ENOENT);
+ }
+ return found;
}
int gss_svc_upcall_install_rvs_ctx(struct obd_import *imp,
- struct gss_sec *gsec,
- struct gss_cli_ctx *gctx)
+ struct gss_sec *gsec,
+ struct gss_cli_ctx *gctx)
{
- struct rsc rsci, *rscp = NULL;
+ struct gss_rsc rsc, *rscp = NULL;
time64_t ctx_expiry;
- __u32 major;
- int rc;
- ENTRY;
+ __u32 major;
+ int rc;
- memset(&rsci, 0, sizeof(rsci));
+ ENTRY;
+ memset(&rsc, 0, sizeof(rsc));
- if (rawobj_alloc(&rsci.handle, (char *) &gsec->gs_rvs_hdl,
- sizeof(gsec->gs_rvs_hdl)))
- GOTO(out, rc = -ENOMEM);
+ if (!imp || !imp->imp_obd) {
+ CERROR("invalid imp, drop\n");
+ RETURN(-EPROTO);
+ }
- rscp = rsc_lookup(&rsci);
- if (rscp == NULL)
- GOTO(out, rc = -ENOMEM);
+ if (rawobj_alloc(&rsc.sc_handle, (char *)&gsec->gs_rvs_hdl,
+ sizeof(gsec->gs_rvs_hdl)))
+ GOTO(out, rc = -ENOMEM);
- major = lgss_copy_reverse_context(gctx->gc_mechctx,
- &rsci.ctx.gsc_mechctx);
- if (major != GSS_S_COMPLETE)
- GOTO(out, rc = -ENOMEM);
+ rscp = rsc_entry_get(rsccache, &rsc);
+ __rsc_free(&rsc);
+ if (IS_ERR_OR_NULL(rscp))
+ GOTO(out, rc = -ENOMEM);
- if (lgss_inquire_context(rsci.ctx.gsc_mechctx, &ctx_expiry)) {
- CERROR("unable to get expire time, drop it\n");
- GOTO(out, rc = -EINVAL);
- }
- rsci.h.expiry_time = ctx_expiry;
+ major = lgss_copy_reverse_context(gctx->gc_mechctx,
+ &rscp->sc_ctx.gsc_mechctx);
+ if (major != GSS_S_COMPLETE)
+ GOTO(out, rc = -ENOMEM);
+
+ if (lgss_inquire_context(rscp->sc_ctx.gsc_mechctx, &ctx_expiry)) {
+ CERROR("%s: unable to get expire time, drop\n",
+ imp->imp_obd->obd_name);
+ GOTO(out, rc = -EINVAL);
+ }
+ rscp->sc_uc_entry->ue_expire = ktime_get_seconds() +
+ (ctx_expiry - ktime_get_real_seconds());
switch (imp->imp_obd->u.cli.cl_sp_to) {
case LUSTRE_SP_MDT:
- rsci.ctx.gsc_usr_mds = 1;
+ rscp->sc_ctx.gsc_usr_mds = 1;
break;
case LUSTRE_SP_OST:
- rsci.ctx.gsc_usr_oss = 1;
+ rscp->sc_ctx.gsc_usr_oss = 1;
break;
case LUSTRE_SP_CLI:
- rsci.ctx.gsc_usr_root = 1;
+ rscp->sc_ctx.gsc_usr_root = 1;
break;
case LUSTRE_SP_MGS:
/* by convention, all 3 set to 1 means MGS */
- rsci.ctx.gsc_usr_mds = 1;
- rsci.ctx.gsc_usr_oss = 1;
- rsci.ctx.gsc_usr_root = 1;
+ rscp->sc_ctx.gsc_usr_mds = 1;
+ rscp->sc_ctx.gsc_usr_oss = 1;
+ rscp->sc_ctx.gsc_usr_root = 1;
break;
default:
break;
}
- rscp = rsc_update(&rsci, rscp);
- if (rscp == NULL)
- GOTO(out, rc = -ENOMEM);
+ rscp->sc_target = imp->imp_obd;
+ rawobj_dup(&gctx->gc_svc_handle, &rscp->sc_handle);
- rscp->target = imp->imp_obd;
- rawobj_dup(&gctx->gc_svc_handle, &rscp->handle);
-
- CDEBUG(D_SEC, "create reverse svc ctx %p to %s: idx %#llx\n",
- &rscp->ctx, obd2cli_tgt(imp->imp_obd), gsec->gs_rvs_hdl);
+ CDEBUG(D_SEC, "%s: create reverse svc ctx %p to %s: idx %#llx\n",
+ imp->imp_obd->obd_name, &rscp->sc_ctx, obd2cli_tgt(imp->imp_obd),
+ gsec->gs_rvs_hdl);
rc = 0;
out:
- if (rscp)
- cache_put(&rscp->h, &rsc_cache);
- rsc_free(&rsci);
-
- if (rc)
- CERROR("create reverse svc ctx: idx %#llx, rc %d\n",
- gsec->gs_rvs_hdl, rc);
- RETURN(rc);
+ if (!IS_ERR_OR_NULL(rscp))
+ rsc_entry_put(rsccache, rscp);
+ if (rc)
+ CERROR("%s: can't create reverse svc ctx idx %#llx: rc = %d\n",
+ imp->imp_obd->obd_name, gsec->gs_rvs_hdl, rc);
+ RETURN(rc);
}
int gss_svc_upcall_expire_rvs_ctx(rawobj_t *handle)
{
const time64_t expire = 20;
- struct rsc *rscp;
+ struct gss_rsc *rscp;
- rscp = gss_svc_searchbyctx(handle);
- if (rscp) {
- CDEBUG(D_SEC, "reverse svcctx %p (rsc %p) expire soon\n",
- &rscp->ctx, rscp);
+ rscp = gss_svc_searchbyctx(handle);
+ if (!IS_ERR_OR_NULL(rscp)) {
+ CDEBUG(D_SEC,
+ "reverse svcctx %p (rsc %p) expire in %lld seconds\n",
+ &rscp->sc_ctx, rscp, expire);
- rscp->h.expiry_time = ktime_get_real_seconds() + expire;
- COMPAT_RSC_PUT(&rscp->h, &rsc_cache);
- }
- return 0;
+ rscp->sc_uc_entry->ue_expire = ktime_get_seconds() + expire;
+ rsc_entry_put(rsccache, rscp);
+ }
+ return 0;
}
int gss_svc_upcall_dup_handle(rawobj_t *handle, struct gss_svc_ctx *ctx)
{
- struct rsc *rscp = container_of(ctx, struct rsc, ctx);
+ struct gss_rsc *rscp = container_of(ctx, struct gss_rsc, sc_ctx);
- return rawobj_dup(handle, &rscp->handle);
+ return rawobj_dup(handle, &rscp->sc_handle);
}
int gss_svc_upcall_update_sequence(rawobj_t *handle, __u32 seq)
{
- struct rsc *rscp;
+ struct gss_rsc *rscp;
- rscp = gss_svc_searchbyctx(handle);
- if (rscp) {
- CDEBUG(D_SEC, "reverse svcctx %p (rsc %p) update seq to %u\n",
- &rscp->ctx, rscp, seq + 1);
+ rscp = gss_svc_searchbyctx(handle);
+ if (!IS_ERR_OR_NULL(rscp)) {
+ CDEBUG(D_SEC, "reverse svcctx %p (rsc %p) update seq to %u\n",
+ &rscp->sc_ctx, rscp, seq + 1);
- rscp->ctx.gsc_rvs_seq = seq + 1;
- COMPAT_RSC_PUT(&rscp->h, &rsc_cache);
- }
- return 0;
+ rscp->sc_ctx.gsc_rvs_seq = seq + 1;
+ rsc_entry_put(rsccache, rscp);
+ }
+ return 0;
}
int gss_svc_upcall_handle_init(struct ptlrpc_request *req,
{
struct gss_rsi rsi = { 0 }, *rsip = NULL;
struct ptlrpc_reply_state *rs;
- struct rsc *rsci = NULL;
+ struct gss_rsc *rscp = NULL;
int replen = sizeof(struct ptlrpc_body);
struct gss_rep_header *rephdr;
- int rc = SECSVC_DROP, rc2;
+ int rc, rc2;
ENTRY;
if (rc2) {
CERROR("%s: failed to duplicate context handle: rc = %d\n",
target->obd_name, rc2);
- GOTO(out, rc);
+ GOTO(out, rc = SECSVC_DROP);
}
rc2 = rawobj_dup(&rsi.si_in_token, in_token);
CERROR("%s: failed to duplicate token: rc = %d\n",
target->obd_name, rc2);
rawobj_free(&rsi.si_in_handle);
- GOTO(out, rc);
+ GOTO(out, rc = SECSVC_DROP);
}
rsip = rsi_entry_get(rsicache, &rsi);
__rsi_free(&rsi);
- if (IS_ERR(rsip)) {
- CERROR("%s: failed to get entry from rsi cache (nid %s): rc = %ld\n",
+ if (IS_ERR_OR_NULL(rsip)) {
+ if (IS_ERR(rsip))
+ rc2 = PTR_ERR(rsip);
+ else
+ rc2 = -EINVAL;
+ CERROR("%s: failed to get entry from rsi cache (nid %s): rc = %d\n",
target->obd_name,
libcfs_nid2str(lnet_nid_to_nid4(&req->rq_source.nid)),
- PTR_ERR(rsip));
+ rc2);
if (!gss_pack_err_notify(req, GSS_S_FAILURE, 0))
rc = SECSVC_COMPLETE;
+ else
+ rc = SECSVC_DROP;
GOTO(out, rc);
}
- rc = SECSVC_DROP;
- rsci = gss_svc_searchbyctx(&rsip->si_out_handle);
- if (!rsci) {
+ rscp = gss_svc_searchbyctx(&rsip->si_out_handle);
+ if (IS_ERR_OR_NULL(rscp)) {
/* gss mechanism returned major and minor code so we return
* those in error message */
+
if (!gss_pack_err_notify(req, rsip->si_major_status,
rsip->si_minor_status))
rc = SECSVC_COMPLETE;
+ else
+ rc = SECSVC_DROP;
CERROR("%s: authentication failed: rc = %d\n",
target->obd_name, rc);
GOTO(out, rc);
} else {
- cache_get(&rsci->h);
- grctx->src_ctx = &rsci->ctx;
+ /* we need to take an extra ref on the cache entry,
+ * as a pointer to sc_ctx is stored in grctx
+ */
+ upcall_cache_get_entry_raw(rscp->sc_uc_entry);
+ grctx->src_ctx = &rscp->sc_ctx;
}
if (gw->gw_flags & LUSTRE_GSS_PACK_KCSUM) {
gss_digest_hash_compat;
}
- if (rawobj_dup(&rsci->ctx.gsc_rvs_hdl, rvs_hdl)) {
+ if (rawobj_dup(&rscp->sc_ctx.gsc_rvs_hdl, rvs_hdl)) {
CERROR("%s: failed duplicate reverse handle\n",
target->obd_name);
- GOTO(out, rc);
+ GOTO(out, rc = SECSVC_DROP);
}
- rsci->target = target;
+ rscp->sc_target = target;
CDEBUG(D_SEC, "%s: server create rsc %p(%u->%s)\n",
- target->obd_name, rsci, rsci->ctx.gsc_uid,
+ target->obd_name, rscp, rscp->sc_ctx.gsc_uid,
libcfs_nidstr(&req->rq_peer.nid));
if (rsip->si_out_handle.len > PTLRPC_GSS_MAX_HANDLE_SIZE) {
out:
if (!IS_ERR_OR_NULL(rsip))
rsi_entry_put(rsicache, rsip);
- if (rsci) {
+ if (!IS_ERR_OR_NULL(rscp)) {
/* if anything went wrong, we don't keep the context too */
if (rc != SECSVC_OK)
- set_bit(CACHE_NEGATIVE, &rsci->h.flags);
+ UC_CACHE_SET_INVALID(rscp->sc_uc_entry);
else
CDEBUG(D_SEC, "%s: create rsc with idx %#llx\n",
target->obd_name,
- gss_handle_to_u64(&rsci->handle));
+ gss_handle_to_u64(&rscp->sc_handle));
- COMPAT_RSC_PUT(&rsci->h, &rsc_cache);
+ rsc_entry_put(rsccache, rscp);
}
RETURN(rc);
}
struct gss_svc_ctx *gss_svc_upcall_get_ctx(struct ptlrpc_request *req,
struct gss_wire_ctx *gw)
{
- struct rsc *rsc;
+ struct gss_rsc *rscp;
- rsc = gss_svc_searchbyctx(&gw->gw_handle);
- if (!rsc) {
+ rscp = gss_svc_searchbyctx(&gw->gw_handle);
+ if (IS_ERR_OR_NULL(rscp)) {
CWARN("Invalid gss ctx idx %#llx from %s\n",
gss_handle_to_u64(&gw->gw_handle),
libcfs_nidstr(&req->rq_peer.nid));
return NULL;
}
- return &rsc->ctx;
+ return &rscp->sc_ctx;
}
void gss_svc_upcall_put_ctx(struct gss_svc_ctx *ctx)
{
- struct rsc *rsc = container_of(ctx, struct rsc, ctx);
+ struct gss_rsc *rscp = container_of(ctx, struct gss_rsc, sc_ctx);
- COMPAT_RSC_PUT(&rsc->h, &rsc_cache);
+ rsc_entry_put(rsccache, rscp);
}
void gss_svc_upcall_destroy_ctx(struct gss_svc_ctx *ctx)
{
- struct rsc *rsc = container_of(ctx, struct rsc, ctx);
+ struct gss_rsc *rscp = container_of(ctx, struct gss_rsc, sc_ctx);
- /* can't be found */
- set_bit(CACHE_NEGATIVE, &rsc->h.flags);
- /* to be removed at next scan */
- rsc->h.expiry_time = 1;
+ UC_CACHE_SET_INVALID(rscp->sc_uc_entry);
+ rscp->sc_uc_entry->ue_expire = 1;
}
/* Wait for userspace daemon to open socket, approx 1.5 s.
rsicache = NULL;
return rc;
}
+ rsccache = upcall_cache_init(RSC_CACHE_NAME, RSC_UPCALL_PATH,
+ UC_RSCCACHE_HASH_SIZE,
+ 3600, /* replaced with one from mech */
+ 100, /* arbitrary, not used */
+ &rsc_upcall_cache_ops);
+ if (IS_ERR(rsccache)) {
+ upcall_cache_cleanup(rsicache);
+ rsicache = NULL;
+ rc = PTR_ERR(rsccache);
+ rsccache = NULL;
+ return rc;
+ }
if (check_gssd_socket())
CDEBUG(D_SEC,
cache_unregister_net(&rsc_cache, &init_net);
upcall_cache_cleanup(rsicache);
+ upcall_cache_cleanup(rsccache);
}
}
LPROC_SEQ_FOPS(rsi_acquire_expire);
+static ssize_t lprocfs_rsc_flush_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, void *data)
+{
+ int hash, rc;
+
+ rc = kstrtoint_from_user(buffer, count, 0, &hash);
+ if (rc)
+ return rc;
+
+ rsc_flush(rsccache, hash);
+ return count;
+}
+LPROC_SEQ_FOPS_WR_ONLY(gss, rsc_flush);
+
+static ssize_t lprocfs_rsc_info_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, void *data)
+{
+ struct rsc_downcall_data *param;
+ int size = sizeof(*param), rc, checked = 0;
+ struct gss_rsc rsc = { 0 }, *rscp = NULL;
+ char *mesg, *handle_buf;
+
+again:
+ if (count < size) {
+ CERROR("%s: invalid data count = %lu, size = %d\n",
+ rsccache->uc_name, (unsigned long)count, size);
+ return -EINVAL;
+ }
+
+ OBD_ALLOC_LARGE(param, size);
+ if (param == NULL)
+ return -ENOMEM;
+
+ if (copy_from_user(param, buffer, size)) {
+ CERROR("%s: bad rsc data\n", rsccache->uc_name);
+ GOTO(out, rc = -EFAULT);
+ }
+
+ if (checked == 0) {
+ checked = 1;
+ if (param->scd_magic != RSC_DOWNCALL_MAGIC) {
+ CERROR("%s: rsc downcall bad params\n",
+ rsccache->uc_name);
+ GOTO(out, rc = -EINVAL);
+ }
+
+ rc = param->scd_len; /* save scd_len */
+ OBD_FREE_LARGE(param, size);
+ size = offsetof(struct rsc_downcall_data, scd_val[rc]);
+ goto again;
+ }
+
+ /* scd_val starts with handle.
+ * Use it to create cache entry.
+ */
+ mesg = param->scd_val;
+ gss_u32_read(&mesg, &rsc.sc_handle.len);
+ if (!rsc.sc_handle.len) {
+ rc = -EINVAL;
+ goto out;
+ }
+ OBD_ALLOC_LARGE(handle_buf, rsc.sc_handle.len);
+ if (!handle_buf) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ memset(handle_buf, 0, rsc.sc_handle.len);
+ mesg = param->scd_val;
+ rc = gss_buffer_read(&mesg, handle_buf, rsc.sc_handle.len);
+ if (rc < 0) {
+ OBD_FREE_LARGE(handle_buf, rsc.sc_handle.len);
+ rc = -EINVAL;
+ goto out;
+ }
+ rsc.sc_handle.data = handle_buf;
+
+ /* create cache entry on-the-fly */
+ rscp = rsc_entry_get(rsccache, &rsc);
+ __rsc_free(&rsc);
+
+ if (IS_ERR_OR_NULL(rscp)) {
+ if (IS_ERR(rscp))
+ rc = PTR_ERR(rscp);
+ else
+ rc = -EINVAL;
+ CERROR("%s: error in rsc_entry_get: rc = %d\n",
+ param->scd_mechname, rc);
+ goto out;
+ }
+
+ /* now that entry has been created, downcall can be done,
+ * but we have to tell acquiring is in progress
+ */
+ upcall_cache_update_entry(rsccache, rscp->sc_uc_entry,
+ 0, UC_CACHE_ACQUIRING);
+ rc = upcall_cache_downcall(rsccache, param->scd_err,
+ rscp->sc_uc_entry->ue_key, param);
+
+out:
+ if (!IS_ERR_OR_NULL(rscp))
+ rsc_entry_put(rsccache, rscp);
+ if (param)
+ OBD_FREE_LARGE(param, size);
+
+ return rc ? rc : count;
+}
+LPROC_SEQ_FOPS_WR_ONLY(gss, rsc_info);
+
static struct ldebugfs_vars gss_debugfs_vars[] = {
{ .name = "replays",
.fops = &gss_proc_oos_fops },
.fops = &rsi_entry_expire_fops },
{ .name = "rsi_acquire_expire",
.fops = &rsi_acquire_expire_fops },
+ { .name = "rsc_flush",
+ .fops = &gss_rsc_flush_fops },
+ { .name = "rsc_info",
+ .fops = &gss_rsc_info_fops },
{ NULL }
};
LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_val) == 0, "found %lld\n",
(long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_val));
+ /* Checks for struct rsc_downcall_data */
+ LASSERTF((int)sizeof(struct rsc_downcall_data) == 48, "found %lld\n",
+ (long long)(int)sizeof(struct rsc_downcall_data));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_magic) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_magic));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_magic) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_magic));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_err) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_err));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_err) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_err));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_flags) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_flags));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_flags) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_flags));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_mapped_uid) == 12, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_mapped_uid));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_mapped_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_mapped_uid));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_uid) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_uid));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_uid));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_gid) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_gid));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_gid));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_mechname) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_mechname));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_mechname) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_mechname));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_offset) == 32, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_offset));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_offset) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_offset));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_len) == 40, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_len));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_len) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_len));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_padding) == 44, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_padding));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_padding) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_padding));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_val) == 48, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_val));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_val) == 0, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_val));
+ LASSERTF(RSC_DATA_FLAG_REMOTE == 0x00000001UL, "found 0x%.8xUL\n",
+ (unsigned)RSC_DATA_FLAG_REMOTE);
+ LASSERTF(RSC_DATA_FLAG_ROOT == 0x00000002UL, "found 0x%.8xUL\n",
+ (unsigned)RSC_DATA_FLAG_ROOT);
+ LASSERTF(RSC_DATA_FLAG_MDS == 0x00000004UL, "found 0x%.8xUL\n",
+ (unsigned)RSC_DATA_FLAG_MDS);
+ LASSERTF(RSC_DATA_FLAG_OSS == 0x00000008UL, "found 0x%.8xUL\n",
+ (unsigned)RSC_DATA_FLAG_OSS);
+
/* Checks for struct llog_gen */
LASSERTF((int)sizeof(struct llog_gen) == 16, "found %lld\n",
(long long)(int)sizeof(struct llog_gen));
ALWAYS_EXCEPT="$RECOVERY_SMALL_EXCEPT "
+if $SHARED_KEY; then
+ always_except LU-17141 133
+fi
+
build_test_filter
require_dsh_mds || exit 0
sleep 5
do_node $set_client $RUNAS_USER touch $testfile
+ # remove from cache, otherwise ACLs will not be fetched from server
+ do_rpc_nodes $set_client cancel_lru_locks
+ do_node $set_client "sync ; echo 3 > /proc/sys/vm/drop_caches"
# ACL masks aren't filtered by nodemap code, so we ignore them
acl_count=$(do_node $get_client getfacl $testfile | grep -v mask |
wc -l)
+ # remove from cache, otherwise ACLs will not be fetched from server
+ do_rpc_nodes $get_client cancel_lru_locks
+ do_node $get_client "sync ; echo 3 > /proc/sys/vm/drop_caches"
do_node $set_client $RUNAS_USER setfacl -m $user:rwx $testfile ||
setfacl_error=1
+ # remove from cache, otherwise ACLs will not be fetched from server
+ do_rpc_nodes $set_client cancel_lru_locks
+ do_node $set_client "sync ; echo 3 > /proc/sys/vm/drop_caches"
# if check setfacl is set to 1, then it's supposed to error
if [ "$check_setfacl" == "1" ]; then
acl_count_post=$(do_node $get_client getfacl $testfile | grep -v mask |
wc -l)
+ # remove from cache, otherwise ACLs will not be fetched from server
+ do_rpc_nodes $get_client cancel_lru_locks
+ do_node $get_client "sync ; echo 3 > /proc/sys/vm/drop_caches"
[ $acl_count -eq $acl_count_post ] && return 0
return 1
}
if $SHARED_KEY; then
always_except LU-14181 64e 64f
+ always_except LU-17127 39o
fi
# skip the grant tests for ARM until they are fixed
gss_buffer_desc ctx_token;
};
-static int
-do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
- gss_OID mechoid, gss_buffer_desc *context_token)
+static int do_svc_downcall(gss_buffer_desc *out_handle, struct svc_cred *cred,
+ gss_OID mechoid, gss_buffer_desc *ctx_token)
{
- FILE *f;
+ struct rsc_downcall_data *rsc_dd;
+ int blen, fd, size, rc = -1;
const char *mechname;
- int err;
+ glob_t path;
+ char *bp;
printerr(LL_INFO, "doing downcall\n");
+
+ size = out_handle->length + sizeof(__u32) +
+ ctx_token->length + sizeof(__u32);
+ blen = size;
+
+ size += offsetof(struct rsc_downcall_data, scd_val[0]);
+ rsc_dd = calloc(1, size);
+ if (!rsc_dd) {
+ printerr(LL_ERR, "malloc downcall data (%d) failed\n", size);
+ return -ENOMEM;
+ }
+ rsc_dd->scd_magic = RSC_DOWNCALL_MAGIC;
+ rsc_dd->scd_err = 0;
+
+ rsc_dd->scd_flags =
+ (cred->cr_remote ? RSC_DATA_FLAG_REMOTE : 0) |
+ (cred->cr_usr_root ? RSC_DATA_FLAG_ROOT : 0) |
+ (cred->cr_usr_mds ? RSC_DATA_FLAG_MDS : 0) |
+ (cred->cr_usr_oss ? RSC_DATA_FLAG_OSS : 0);
+ rsc_dd->scd_mapped_uid = cred->cr_mapped_uid;
+ rsc_dd->scd_uid = cred->cr_uid;
+ rsc_dd->scd_gid = cred->cr_gid;
mechname = gss_OID_mech_name(mechoid);
if (mechname == NULL)
- goto out_err;
- f = fopen(SVCGSSD_CONTEXT_CHANNEL, "w");
- if (f == NULL) {
- printerr(LL_ERR, "ERROR: unable to open downcall channel "
- "%s: %s\n",
- SVCGSSD_CONTEXT_CHANNEL, strerror(errno));
- goto out_err;
+ goto out;
+ if (snprintf(rsc_dd->scd_mechname, sizeof(rsc_dd->scd_mechname),
+ "%s", mechname) >= sizeof(rsc_dd->scd_mechname))
+ goto out;
+
+ bp = rsc_dd->scd_val;
+ gss_buffer_write(&bp, &blen, out_handle->value, out_handle->length);
+ gss_buffer_write(&bp, &blen, ctx_token->value, ctx_token->length);
+ if (blen < 0) {
+ printerr(LL_ERR, "ERROR: %s: message too long > %d\n",
+ __func__, size);
+ rc = -EMSGSIZE;
+ goto out;
}
- qword_printhex(f, out_handle->value, out_handle->length);
- /* XXX are types OK for the rest of this? */
- qword_printint(f, time(NULL) + 3600); /* 1 hour should be ok */
- qword_printint(f, cred->cr_remote);
- qword_printint(f, cred->cr_usr_root);
- qword_printint(f, cred->cr_usr_mds);
- qword_printint(f, cred->cr_usr_oss);
- qword_printint(f, cred->cr_mapped_uid);
- qword_printint(f, cred->cr_uid);
- qword_printint(f, cred->cr_gid);
- qword_print(f, mechname);
- qword_printhex(f, context_token->value, context_token->length);
- err = qword_eol(f);
- fclose(f);
- return err;
-out_err:
- printerr(LL_ERR, "ERROR: downcall failed\n");
- return -1;
+ rsc_dd->scd_len = bp - rsc_dd->scd_val;
+
+ rc = cfs_get_param_paths(&path, RSC_DOWNCALL_PATH);
+ if (rc != 0) {
+ rc = -errno;
+ goto out;
+ }
+
+ fd = open(path.gl_pathv[0], O_WRONLY);
+ if (fd == -1) {
+ rc = -errno;
+ printerr(LL_ERR, "ERROR: %s: open %s failed: %s\n",
+ __func__, RSC_DOWNCALL_PATH, strerror(-rc));
+ goto out_path;
+ }
+ size = offsetof(struct rsc_downcall_data,
+ scd_val[bp - rsc_dd->scd_val]);
+ printerr(LL_DEBUG, "writing downcall data, size %d\n", size);
+ if (write(fd, rsc_dd, size) == -1) {
+ rc = -errno;
+ printerr(LL_ERR, "ERROR: %s: failed to write message: %s\n",
+ __func__, strerror(-rc));
+ }
+ printerr(LL_DEBUG, "downcall data written ok\n");
+
+ close(fd);
+out_path:
+ cfs_free_param_data(&path);
+out:
+ free(rsc_dd);
+ if (rc)
+ printerr(LL_ERR, "ERROR: downcall failed\n");
+ return rc;
}
struct gss_verifier {
}
static void
+check_rsc_downcall_data(void)
+{
+ BLANK_LINE();
+ CHECK_STRUCT(rsc_downcall_data);
+ CHECK_MEMBER(rsc_downcall_data, scd_magic);
+ CHECK_MEMBER(rsc_downcall_data, scd_err);
+ CHECK_MEMBER(rsc_downcall_data, scd_flags);
+ CHECK_MEMBER(rsc_downcall_data, scd_mapped_uid);
+ CHECK_MEMBER(rsc_downcall_data, scd_uid);
+ CHECK_MEMBER(rsc_downcall_data, scd_gid);
+ CHECK_MEMBER(rsc_downcall_data, scd_mechname);
+ CHECK_MEMBER(rsc_downcall_data, scd_offset);
+ CHECK_MEMBER(rsc_downcall_data, scd_len);
+ CHECK_MEMBER(rsc_downcall_data, scd_padding);
+ CHECK_MEMBER(rsc_downcall_data, scd_val);
+
+ CHECK_VALUE_X(RSC_DATA_FLAG_REMOTE);
+ CHECK_VALUE_X(RSC_DATA_FLAG_ROOT);
+ CHECK_VALUE_X(RSC_DATA_FLAG_MDS);
+ CHECK_VALUE_X(RSC_DATA_FLAG_OSS);
+}
+
+static void
check_llog_gen(void)
{
BLANK_LINE();
check_llog_changelog_user_rec();
#endif /* !HAVE_NATIVE_LINUX_CLIENT */
check_rsi_downcall_data();
+ check_rsc_downcall_data();
check_llog_gen();
check_llog_gen_rec();
check_llog_log_hdr();
LASSERTF((int)sizeof(((struct rsi_downcall_data *)0)->sid_val) == 0, "found %lld\n",
(long long)(int)sizeof(((struct rsi_downcall_data *)0)->sid_val));
+ /* Checks for struct rsc_downcall_data */
+ LASSERTF((int)sizeof(struct rsc_downcall_data) == 48, "found %lld\n",
+ (long long)(int)sizeof(struct rsc_downcall_data));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_magic) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_magic));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_magic) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_magic));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_err) == 4, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_err));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_err) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_err));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_flags) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_flags));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_flags) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_flags));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_mapped_uid) == 12, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_mapped_uid));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_mapped_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_mapped_uid));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_uid) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_uid));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_uid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_uid));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_gid) == 20, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_gid));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_gid) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_gid));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_mechname) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_mechname));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_mechname) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_mechname));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_offset) == 32, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_offset));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_offset) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_offset));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_len) == 40, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_len));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_len) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_len));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_padding) == 44, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_padding));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_padding) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_padding));
+ LASSERTF((int)offsetof(struct rsc_downcall_data, scd_val) == 48, "found %lld\n",
+ (long long)(int)offsetof(struct rsc_downcall_data, scd_val));
+ LASSERTF((int)sizeof(((struct rsc_downcall_data *)0)->scd_val) == 0, "found %lld\n",
+ (long long)(int)sizeof(((struct rsc_downcall_data *)0)->scd_val));
+ LASSERTF(RSC_DATA_FLAG_REMOTE == 0x00000001UL, "found 0x%.8xUL\n",
+ (unsigned)RSC_DATA_FLAG_REMOTE);
+ LASSERTF(RSC_DATA_FLAG_ROOT == 0x00000002UL, "found 0x%.8xUL\n",
+ (unsigned)RSC_DATA_FLAG_ROOT);
+ LASSERTF(RSC_DATA_FLAG_MDS == 0x00000004UL, "found 0x%.8xUL\n",
+ (unsigned)RSC_DATA_FLAG_MDS);
+ LASSERTF(RSC_DATA_FLAG_OSS == 0x00000008UL, "found 0x%.8xUL\n",
+ (unsigned)RSC_DATA_FLAG_OSS);
+
/* Checks for struct llog_gen */
LASSERTF((int)sizeof(struct llog_gen) == 16, "found %lld\n",
(long long)(int)sizeof(struct llog_gen));