Whamcloud - gitweb
LU-7093 mdt: Remote operation permission check 86/16286/6
authorwang di <di.wang@intel.com>
Fri, 4 Sep 2015 08:48:32 +0000 (01:48 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 17 Sep 2015 16:40:31 +0000 (16:40 +0000)
Only do permission check for migrate, create striped (remote)
directory, and set default LMV stripeEA for directory.

For non-administrators, only if their gid match
enable_remote_dir_gid (under /proc) or
enable_remote_dir_gid = -1, then they can do these above 3
operations.

Signed-off-by: wang di <di.wang@intel.com>
Change-Id: Id103ddd4dbf4a1901a32b599639037de8ce58e4a
Reviewed-on: http://review.whamcloud.com/16286
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Lai Siyao <lai.siyao@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/mdt/mdt_reint.c
lustre/tests/sanity.sh

index defdb39..6480510 100644 (file)
@@ -220,64 +220,73 @@ static int mdt_lookup_version_check(struct mdt_thread_info *info,
 
 }
 
+static inline int mdt_remote_permission_check(struct mdt_thread_info *info)
+{
+       struct lu_ucred *uc  = mdt_ucred(info);
+       struct mdt_device *mdt = info->mti_mdt;
+
+       if (!md_capable(uc, CFS_CAP_SYS_ADMIN)) {
+               if (uc->uc_gid != mdt->mdt_enable_remote_dir_gid &&
+                   mdt->mdt_enable_remote_dir_gid != -1)
+                       return -EPERM;
+       }
+
+       return 0;
+}
+
 /**
  * mdt_remote_permission: Check whether the remote operation is permitted,
  *
- * Before we implement async cross-MDT updates (DNE phase 2). There are a few
- * limitations here:
- *
- * 1.Only sysadmin can create remote directory and striped directory and
- *   migrate directory now, unless
- *   lctl set_param mdt.*.enable_remote_dir_gid=allow_gid.
- * 2.Remote directory can only be created on MDT0, unless
- *   lctl set_param mdt.*.enable_remote_dir = 1
- * 3.Only new clients can access remote dir( >= 2.4) and striped dir(>= 2.6),
- *   old client will return -ENOTSUPP.
+ * Only sysadmin can create remote directory / striped directory,
+ * migrate directory and set default stripedEA on directory, unless
  *
- * XXX these check are only needed for remote synchronization, once async
- * update is supported, these check will be removed.
+ * lctl set_param mdt.*.enable_remote_dir_gid=allow_gid.
  *
- * param[in]info:      execution environment.
- * param[in]parent:    the directory of this operation.
- * param[in]child:     the child of this operation.
+ * param[in] info: mdt_thread_info.
  *
  * retval      = 0 remote operation is allowed.
  *              < 0 remote operation is denied.
  */
-static int mdt_remote_permission(struct mdt_thread_info *info,
-                                struct mdt_object *parent,
-                                struct mdt_object *child)
+static int mdt_remote_permission(struct mdt_thread_info *info)
 {
-       struct mdt_device       *mdt = info->mti_mdt;
-       struct lu_ucred         *uc  = mdt_ucred(info);
-       struct md_op_spec       *spec = &info->mti_spec;
-       struct lu_attr          *attr = &info->mti_attr.ma_attr;
-       struct obd_export       *exp = mdt_info_req(info)->rq_export;
-
-       /* Only check create remote directory, striped directory and
-        * migration */
-       if (mdt_object_remote(parent) == 0 && mdt_object_remote(child) == 0 &&
-           !(S_ISDIR(attr->la_mode) && spec->u.sp_ea.eadata != NULL &&
-                                       spec->u.sp_ea.eadatalen != 0) &&
-           info->mti_rr.rr_opcode != REINT_MIGRATE)
-               return 0;
+       struct md_op_spec *spec = &info->mti_spec;
+       struct lu_attr *attr = &info->mti_attr.ma_attr;
+       struct obd_export *exp = mdt_info_req(info)->rq_export;
+       int rc;
 
-       if (!md_capable(uc, CFS_CAP_SYS_ADMIN)) {
-               if (uc->uc_gid != mdt->mdt_enable_remote_dir_gid &&
-                   mdt->mdt_enable_remote_dir_gid != -1)
-                       return -EPERM;
+       if (info->mti_rr.rr_opcode == REINT_MIGRATE) {
+               rc = mdt_remote_permission_check(info);
+               if (rc != 0)
+                       return rc;
        }
 
-       if (!mdt_is_dne_client(exp))
-               return -ENOTSUPP;
-
-       if (S_ISDIR(attr->la_mode) && spec->u.sp_ea.eadata != NULL &&
-           spec->u.sp_ea.eadatalen != 0) {
+       if (info->mti_rr.rr_opcode == REINT_CREATE &&
+           (S_ISDIR(attr->la_mode) && spec->u.sp_ea.eadata != NULL &&
+            spec->u.sp_ea.eadatalen != 0)) {
                const struct lmv_user_md *lum = spec->u.sp_ea.eadata;
 
+               /* Only new clients can create remote dir( >= 2.4) and
+                * striped dir(>= 2.6), old client will return -ENOTSUPP */
+               if (!mdt_is_dne_client(exp))
+                       return -ENOTSUPP;
+
                if (le32_to_cpu(lum->lum_stripe_count) > 1 &&
                    !mdt_is_striped_client(exp))
                        return -ENOTSUPP;
+
+               rc = mdt_remote_permission_check(info);
+               if (rc != 0)
+                       return rc;
+       }
+
+       if (info->mti_rr.rr_opcode == REINT_SETATTR) {
+               struct md_attr *ma = &info->mti_attr;
+
+               if ((ma->ma_valid & MA_LMV)) {
+                       rc = mdt_remote_permission_check(info);
+                       if (rc != 0)
+                               return rc;
+               }
        }
 
        return 0;
@@ -351,7 +360,7 @@ static int mdt_md_create(struct mdt_thread_info *info)
         if (likely(!IS_ERR(child))) {
                 struct md_object *next = mdt_object_child(parent);
 
-               rc = mdt_remote_permission(info, parent, child);
+               rc = mdt_remote_permission(info);
                if (rc != 0)
                        GOTO(out_put_child, rc);
 
@@ -668,6 +677,10 @@ static int mdt_reint_setattr(struct mdt_thread_info *info,
                struct lu_buf *buf  = &info->mti_buf;
                struct mdt_lock_handle  *lh;
 
+               rc = mdt_remote_permission(info);
+               if (rc < 0)
+                       GOTO(out_put, rc);
+
                if (ma->ma_attr.la_valid != 0)
                        GOTO(out_put, rc = -EPROTO);
 
@@ -1414,7 +1427,7 @@ static int mdt_reint_migrate_internal(struct mdt_thread_info *info,
                GOTO(out_put_child, rc = -EPERM);
        }
 
-       rc = mdt_remote_permission(info, msrcdir, mold);
+       rc = mdt_remote_permission(info);
        if (rc != 0)
                GOTO(out_put_child, rc);
 
index e546fa3..4f78323 100644 (file)
@@ -13841,6 +13841,52 @@ test_300m() {
 }
 run_test 300m "setstriped directory on single MDT FS"
 
+cleanup_300n() {
+       local list=$(comma_list $(mdts_nodes))
+
+       trap 0
+       do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
+}
+
+test_300n() {
+       [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
+       [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
+       local stripe_index
+       local list=$(comma_list $(mdts_nodes))
+
+       trap cleanup_300n RETURN EXIT
+       mkdir -p $DIR/$tdir
+       chmod 777 $DIR/$tdir
+       $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
+                               $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
+               error "create striped dir succeeds with gid=0"
+
+       do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
+       $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
+               error "create striped dir fails with gid=-1"
+
+       do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
+       $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
+                               $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
+               error "set default striped dir succeeds with gid=0"
+
+
+       do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
+       $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
+               error "set default striped dir fails with gid=-1"
+
+
+       do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
+       $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
+                                       error "create test_dir fails"
+       $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
+                                       error "create test_dir1 fails"
+       $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
+                                       error "create test_dir2 fails"
+       cleanup_300n
+}
+run_test 300n "non-root user to create dir under striped dir with default EA"
+
 prepare_remote_file() {
        mkdir $DIR/$tdir/src_dir ||
                error "create remote source failed"