From: Kit Westneat Date: Tue, 13 Oct 2015 02:58:18 +0000 (-0400) Subject: LU-7199 nodemap: assign nodemap to export before connecting X-Git-Tag: 2.7.64~18 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=2aea469a3a6e214db485b091e92d8bca84af4f51 LU-7199 nodemap: assign nodemap to export before connecting This patch moves the nodemap assignment to be before the connection is active, and the nodemap deassignemnt to be after the connection is made inactive. It also checks for null nodemaps and returns -EACCES if the nodemap is not set in order to avoid a kernel panic. Signed-off-by: Kit Westneat Change-Id: Id4dd02cf5b4208bda6d6f17aed6adb13b18c7731 Reviewed-on: http://review.whamcloud.com/16802 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: John L. Hammond Reviewed-by: Oleg Drokin --- diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 842f50d..e27fee3 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -5004,12 +5004,12 @@ static int mdt_obd_disconnect(struct obd_export *exp) LASSERT(exp); class_export_get(exp); - nodemap_del_member(exp); rc = server_disconnect_export(exp); if (rc != 0) CDEBUG(D_IOCTL, "server disconnect error: rc = %d\n", rc); rc = mdt_export_cleanup(exp); + nodemap_del_member(exp); class_export_put(exp); RETURN(rc); } @@ -5057,6 +5057,10 @@ static int mdt_obd_connect(const struct lu_env *env, lexp = class_conn2export(&conn); LASSERT(lexp != NULL); + rc = nodemap_add_member(*client_nid, lexp); + if (rc != 0 && rc != -EEXIST) + GOTO(out, rc); + rc = mdt_connect_internal(lexp, mdt, data); if (rc == 0) { struct lsd_client_data *lcd = lexp->exp_target_data.ted_lcd; @@ -5064,17 +5068,13 @@ static int mdt_obd_connect(const struct lu_env *env, LASSERT(lcd); memcpy(lcd->lcd_uuid, cluuid, sizeof lcd->lcd_uuid); rc = tgt_client_new(env, lexp); - if (rc == 0) { - rc = nodemap_add_member(*client_nid, lexp); - if (rc != 0 && rc != -EEXIST) - goto out; - + if (rc == 0) mdt_export_stats_init(obd, lexp, localdata); - } } out: if (rc != 0) { class_disconnect(lexp); + nodemap_del_member(lexp); *exp = NULL; } else { *exp = lexp; @@ -5096,12 +5096,15 @@ static int mdt_obd_reconnect(const struct lu_env *env, if (exp == NULL || obd == NULL || cluuid == NULL) RETURN(-EINVAL); + rc = nodemap_add_member(*client_nid, exp); + if (rc != 0 && rc != -EEXIST) + RETURN(rc); + rc = mdt_connect_internal(exp, mdt_dev(obd->obd_lu_dev), data); - if (rc == 0) { - rc = nodemap_add_member(*client_nid, exp); - if (rc == 0 || rc == -EEXIST) - mdt_export_stats_init(obd, exp, localdata); - } + if (rc == 0) + mdt_export_stats_init(obd, exp, localdata); + else + nodemap_del_member(exp); RETURN(rc); } diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 298f058..6d03fee 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -463,27 +463,62 @@ out: return rc; } -static void mdt_squash_nodemap_id(struct lu_ucred *ucred, - struct lu_nodemap *nodemap) +static int old_init_ucred_common(struct mdt_thread_info *info, + bool drop_fs_cap) { - if (ucred->uc_o_uid == nodemap->nm_squash_uid) { - ucred->uc_fsuid = nodemap->nm_squash_uid; - ucred->uc_fsgid = nodemap->nm_squash_gid; - ucred->uc_cap = 0; - ucred->uc_suppgids[0] = -1; - ucred->uc_suppgids[1] = -1; + struct lu_ucred *uc = mdt_ucred(info); + struct mdt_device *mdt = info->mti_mdt; + struct md_identity *identity = NULL; + struct lu_nodemap *nodemap = + info->mti_exp->exp_target_data.ted_nodemap; + + if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { + identity = mdt_identity_get(mdt->mdt_identity_cache, + uc->uc_fsuid); + if (IS_ERR(identity)) { + if (unlikely(PTR_ERR(identity) == -EREMCHG)) { + identity = NULL; + } else { + CDEBUG(D_SEC, "Deny access without identity: " + "uid %u\n", uc->uc_fsuid); + RETURN(-EACCES); + } + } } -} + uc->uc_identity = identity; + if (nodemap == NULL) { + CERROR("%s: cli %s/%p nodemap not set.\n", + mdt2obd_dev(mdt)->obd_name, + info->mti_exp->exp_client_uuid.uuid, info->mti_exp); + RETURN(-EACCES); + } else if (uc->uc_o_uid == nodemap->nm_squash_uid) { + uc->uc_fsuid = nodemap->nm_squash_uid; + uc->uc_fsgid = nodemap->nm_squash_gid; + uc->uc_cap = 0; + uc->uc_suppgids[0] = -1; + uc->uc_suppgids[1] = -1; + } + + /* process root_squash here. */ + mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid); + + /* remove fs privilege for non-root user. */ + if (uc->uc_fsuid) + uc->uc_cap &= ~CFS_CAP_FS_MASK; + uc->uc_valid = UCRED_OLD; + ucred_set_jobid(info, uc); + + return 0; +} static int old_init_ucred(struct mdt_thread_info *info, struct mdt_body *body, bool drop_fs_cap) { struct lu_ucred *uc = mdt_ucred(info); - struct mdt_device *mdt = info->mti_mdt; - struct md_identity *identity = NULL; struct lu_nodemap *nodemap = info->mti_exp->exp_target_data.ted_nodemap; + int rc; ENTRY; body->mbo_uid = nodemap_map_id(nodemap, NODEMAP_UID, @@ -504,44 +539,19 @@ static int old_init_ucred(struct mdt_thread_info *info, uc->uc_suppgids[0] = body->mbo_suppgid; uc->uc_suppgids[1] = -1; uc->uc_ginfo = NULL; - if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { - identity = mdt_identity_get(mdt->mdt_identity_cache, - uc->uc_fsuid); - if (IS_ERR(identity)) { - if (unlikely(PTR_ERR(identity) == -EREMCHG)) { - identity = NULL; - } else { - CDEBUG(D_SEC, "Deny access without identity: " - "uid %u\n", uc->uc_fsuid); - RETURN(-EACCES); - } - } - } - uc->uc_identity = identity; - - mdt_squash_nodemap_id(uc, nodemap); + uc->uc_cap = body->mbo_capability; - /* process root_squash here. */ - mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid); + rc = old_init_ucred_common(info, drop_fs_cap); - /* remove fs privilege for non-root user. */ - if (uc->uc_fsuid && drop_fs_cap) - uc->uc_cap = body->mbo_capability & ~CFS_CAP_FS_MASK; - else - uc->uc_cap = body->mbo_capability; - uc->uc_valid = UCRED_OLD; - ucred_set_jobid(info, uc); - - RETURN(0); + RETURN(rc); } static int old_init_ucred_reint(struct mdt_thread_info *info) { struct lu_ucred *uc = mdt_ucred(info); - struct mdt_device *mdt = info->mti_mdt; - struct md_identity *identity = NULL; struct lu_nodemap *nodemap = info->mti_exp->exp_target_data.ted_nodemap; + int rc; ENTRY; LASSERT(uc != NULL); @@ -556,31 +566,9 @@ static int old_init_ucred_reint(struct mdt_thread_info *info) uc->uc_o_gid = uc->uc_o_fsgid = uc->uc_gid = uc->uc_fsgid; uc->uc_ginfo = NULL; - if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { - identity = mdt_identity_get(mdt->mdt_identity_cache, - uc->uc_fsuid); - if (IS_ERR(identity)) { - if (unlikely(PTR_ERR(identity) == -EREMCHG)) { - identity = NULL; - } else { - CDEBUG(D_SEC, "Deny access without identity: " - "uid %u\n", uc->uc_fsuid); - RETURN(-EACCES); - } - } - } - uc->uc_identity = identity; + rc = old_init_ucred_common(info, true); /* drop_fs_cap = true */ - /* process root_squash here. */ - mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid); - - /* remove fs privilege for non-root user. */ - if (uc->uc_fsuid) - uc->uc_cap &= ~CFS_CAP_FS_MASK; - uc->uc_valid = UCRED_OLD; - ucred_set_jobid(info, uc); - - RETURN(0); + RETURN(rc); } static inline int __mdt_init_ucred(struct mdt_thread_info *info, diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index 515dba9..2d73ae5 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -297,13 +297,17 @@ static int ofd_obd_reconnect(const struct lu_env *env, struct obd_export *exp, if (exp == NULL || obd == NULL || cluuid == NULL) RETURN(-EINVAL); + rc = nodemap_add_member(*(lnet_nid_t *)client_nid, exp); + if (rc != 0 && rc != -EEXIST) + RETURN(rc); + ofd = ofd_dev(obd->obd_lu_dev); rc = ofd_parse_connect_data(env, exp, data, false); if (rc == 0) ofd_export_stats_init(ofd, exp, client_nid); - - nodemap_add_member(*(lnet_nid_t *)client_nid, exp); + else + nodemap_del_member(exp); RETURN(rc); } @@ -333,7 +337,6 @@ static int ofd_obd_connect(const struct lu_env *env, struct obd_export **_exp, struct ofd_device *ofd; struct lustre_handle conn = { 0 }; int rc; - lnet_nid_t *client_nid; ENTRY; if (_exp == NULL || obd == NULL || cluuid == NULL) @@ -348,15 +351,19 @@ static int ofd_obd_connect(const struct lu_env *env, struct obd_export **_exp, exp = class_conn2export(&conn); LASSERT(exp != NULL); + if (localdata != NULL) { + rc = nodemap_add_member(*(lnet_nid_t *)localdata, exp); + if (rc != 0 && rc != -EEXIST) + GOTO(out, rc); + } else { + CDEBUG(D_HA, "%s: cannot find nodemap for client %s: " + "nid is null\n", obd->obd_name, cluuid->uuid); + } + rc = ofd_parse_connect_data(env, exp, data, true); if (rc) GOTO(out, rc); - if (localdata != NULL) { - client_nid = localdata; - nodemap_add_member(*client_nid, exp); - } - if (obd->obd_replayable) { struct tg_export_data *ted = &exp->exp_target_data; @@ -373,8 +380,8 @@ static int ofd_obd_connect(const struct lu_env *env, struct obd_export **_exp, out: if (rc != 0) { - nodemap_del_member(exp); class_disconnect(exp); + nodemap_del_member(exp); *_exp = NULL; } else { *_exp = exp; @@ -407,7 +414,6 @@ int ofd_obd_disconnect(struct obd_export *exp) if (!(exp->exp_flags & OBD_OPT_FORCE)) ofd_grant_sanity_check(ofd_obd(ofd), __FUNCTION__); - nodemap_del_member(exp); rc = server_disconnect_export(exp); ofd_grant_discard(exp); @@ -423,6 +429,7 @@ int ofd_obd_disconnect(struct obd_export *exp) lu_env_fini(&env); } out: + nodemap_del_member(exp); class_export_put(exp); RETURN(rc); }