Whamcloud - gitweb
LU-7199 nodemap: assign nodemap to export before connecting 02/16802/7
authorKit Westneat <kit.westneat@gmail.com>
Tue, 13 Oct 2015 02:58:18 +0000 (22:58 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Wed, 2 Dec 2015 03:54:58 +0000 (03:54 +0000)
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 <kit.westneat@gmail.com>
Change-Id: Id4dd02cf5b4208bda6d6f17aed6adb13b18c7731
Reviewed-on: http://review.whamcloud.com/16802
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_lib.c
lustre/ofd/ofd_obd.c

index 842f50d..e27fee3 100644 (file)
@@ -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);
 }
index 298f058..6d03fee 100644 (file)
@@ -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,
index 515dba9..2d73ae5 100644 (file)
@@ -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);
 }