Whamcloud - gitweb
LU-10499 pcc: tunable GID to pin/unpin files 63/54463/5
authorQian Yingjin <qian@ddn.com>
Thu, 21 Apr 2022 02:13:13 +0000 (22:13 -0400)
committerOleg Drokin <green@whamcloud.com>
Wed, 22 Jan 2025 18:41:22 +0000 (18:41 +0000)
In this patch, we adds a tunable "mdt.*.enable_pin_gid" that
controls the GID to pin/unpin files.
Default should be gid=0, so it is limited to root, gid=-1 so any
user can pin/unpin, or gid=<gid> to allow a specific GID (e.g.
wheel).
We add a virtual "lustre.pin" xattr to set/get the xattr for
non-root users, if mdt.*.enable_pin_gid is set correctly.
Add test case sanity-pcc test_204b to verify it.

EX-bug-id: EX-5047
Change-Id: I1be92f365cfe8dea278559b2c34fcee8e42d1c4d
Signed-off-by: Qian Yingjin <qian@ddn.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/54463
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Feng Lei <flei@ddn.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/xattr.c
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_lproc.c
lustre/mdt/mdt_xattr.c
lustre/tests/sanity-pcc.sh
lustre/utils/liblustreapi_pcc.c

index 42fc4ab..1095a08 100644 (file)
@@ -821,6 +821,7 @@ static inline bool lov_pool_is_reserved(const char *pool)
 #define LOV_V1_INSANE_STRIPE_COUNT LOV_V1_INSANE_STRIPE_INDEX /* deprecated */
 
 #define XATTR_LUSTRE_PREFIX    "lustre."
+#define XATTR_LUSTRE_PIN       XATTR_LUSTRE_PREFIX"pin"
 #define XATTR_LUSTRE_LOV       XATTR_LUSTRE_PREFIX"lov"
 
 /* Please update if XATTR_LUSTRE_LOV".set" groks more flags in the future */
index fdf3ad9..e5c9216 100644 (file)
@@ -474,7 +474,8 @@ int ll_xattr_list(struct inode *inode, const char *name, int type, void *buffer,
 
        if (sbi->ll_xattr_cache_enabled && type != XATTR_ACL_ACCESS_T &&
            (type != XATTR_SECURITY_T || !ll_xattr_is_seclabel(name)) &&
-           (type != XATTR_TRUSTED_T || strcmp(name, XATTR_NAME_SOM))) {
+           (type != XATTR_TRUSTED_T || strcmp(name, XATTR_NAME_SOM)) &&
+           (type != XATTR_LUSTRE_T || strcmp(name, XATTR_LUSTRE_PIN))) {
                rc = ll_xattr_cache_get(inode, name, buffer, size, valid);
                if (rc == -EAGAIN)
                        goto getxattr_nocache;
index 25f27e8..5103049 100644 (file)
@@ -6435,6 +6435,7 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m,
        m->mdt_enable_parallel_rename_crossdir = 1;
        m->mdt_enable_remote_dir = 1;
        m->mdt_enable_remote_dir_gid = 0;
+       m->mdt_enable_pin_gid = 0;
        m->mdt_enable_remote_rename = 1;
        m->mdt_enable_striped_dir = 1;
        m->mdt_enable_dmv_implicit_inherit = 1;
index e76ce9e..96511cb 100644 (file)
@@ -327,6 +327,8 @@ struct mdt_device {
                                   /* user with this gid can change projid */
        gid_t                      mdt_enable_chprojid_gid;
        kernel_cap_t               mdt_enable_cap_mask;
+                                  /* user with this gid can pin/unpin file */
+       gid_t                      mdt_enable_pin_gid;
 
        /* lock for osfs and md_root */
        spinlock_t                 mdt_lock;
index 21f5ed2..775afbc 100644 (file)
@@ -867,6 +867,37 @@ MDT_BOOL_RW_ATTR(enable_strict_som);
 MDT_BOOL_RW_ATTR(enable_dmv_implicit_inherit);
 MDT_BOOL_RW_ATTR(enable_dmv_xattr);
 
+static ssize_t enable_pin_gid_show(struct kobject *kobj,
+                                  struct attribute *attr, char *buf)
+{
+       struct obd_device *obd = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
+       struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+
+       if (mdt->mdt_enable_pin_gid == ~0U)
+               return scnprintf(buf, PAGE_SIZE, "-1\n");
+       return scnprintf(buf, PAGE_SIZE, "%u\n", mdt->mdt_enable_pin_gid);
+}
+
+static ssize_t enable_pin_gid_store(struct kobject *kobj,
+                                   struct attribute *attr,
+                                   const char *buffer, size_t count)
+{
+       struct obd_device *obd = container_of(kobj, struct obd_device,
+                                             obd_kset.kobj);
+       struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+       int val;
+       int rc;
+
+       rc = kstrtoint(buffer, 0, &val);
+       if (rc)
+               return rc;
+
+       mdt->mdt_enable_pin_gid = val;
+       return count;
+}
+LUSTRE_RW_ATTR(enable_pin_gid);
+
 /**
  * Show if the MDT is in no create mode.
  *
@@ -1452,6 +1483,7 @@ static struct attribute *mdt_attrs[] = {
        &lustre_attr_evict_tgt_nids.attr,
        &lustre_attr_enable_cap_mask.attr,
        &lustre_attr_enable_chprojid_gid.attr,
+       &lustre_attr_enable_pin_gid.attr,
        &lustre_attr_enable_dir_migration.attr,
        &lustre_attr_enable_dir_restripe.attr,
        &lustre_attr_enable_dir_auto_split.attr,
index f2f1c47..7fc93bd 100644 (file)
@@ -73,6 +73,9 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info *info)
                    !strncmp(xattr_name, user_string, sizeof(user_string) - 1))
                        RETURN(-EOPNOTSUPP);
 
+               if (strcmp(xattr_name, XATTR_LUSTRE_PIN) == 0)
+                       xattr_name = XATTR_NAME_PIN;
+
                size = mo_xattr_get(info->mti_env,
                                    mdt_object_child(info->mti_object),
                                    &LU_BUF_NULL, xattr_name);
@@ -286,6 +289,10 @@ int mdt_getxattr(struct mdt_thread_info *info)
        if (valid == OBD_MD_FLXATTR) {
                const char *xattr_name = req_capsule_client_get(info->mti_pill,
                                                                &RMF_NAME);
+
+               if (strcmp(xattr_name, XATTR_LUSTRE_PIN) == 0)
+                       xattr_name = XATTR_NAME_PIN;
+
                rc = mo_xattr_get(info->mti_env, next, buf, xattr_name);
                if (rc < 0)
                        GOTO(out, rc);
@@ -602,6 +609,16 @@ int mdt_reint_setxattr(struct mdt_thread_info *info,
                }
 
                lockpart |= MDS_INODELOCK_LAYOUT;
+       } else if ((strcmp(xattr_name, XATTR_LUSTRE_PIN) == 0)) {
+               struct mdt_device *mdt = info->mti_mdt;
+               struct lu_ucred *uc = mdt_ucred(info);
+
+               if (!cap_raised(uc->uc_cap, CAP_SYS_RESOURCE) &&
+                   !lustre_in_group_p(uc, mdt->mdt_enable_pin_gid) &&
+                   !(mdt->mdt_enable_pin_gid == -1))
+                       GOTO(out, rc = -EPERM);
+
+               xattr_name = XATTR_NAME_PIN;
        }
 
        if (!strcmp(xattr_name, XATTR_NAME_ACL_ACCESS))
index 9f2cb6c..f09bd20 100755 (executable)
@@ -4692,6 +4692,54 @@ test_204a() {
 run_test 204a "pin/unpin pcc flag"
 
 test_204b() {
+       local id="100"
+       local dir=$DIR/$tdir
+       local file=$dir/$tfile
+       local old
+
+       $LCTL get_param -n mdc.*.connect_flags | grep -q pcc_ro ||
+               skip "Server does not support PCC-RO"
+
+       (( $MDS1_VERSION >= $(version_code 2.15.61) )) ||
+               skip "Need server version at least 2.15.61"
+
+       old=$(do_facet mds1 $LCTL get_param -n mdt.*.enable_pin_gid | head -1)
+       do_facet mds1 $LCTL set_param mdt.*.enable_pin_gid=0
+       stack_trap "do_facet mds1 $LCTL set_param mdt.*.enable_pin_gid=$old"
+
+       mkdir_on_mdt0 -p $dir || error "mkdir $dir failed"
+       chmod 777 $dir || error "chown $dir failed"
+       $RUNAS touch $file || error "touch $file failed"
+       $RUNAS $LFS pcc pin -i $id $file &&
+               error "normal user should not able to pin any file"
+       $LFS pcc pin -i $id $file || error "root should be able to pin any file"
+       getfattr -d -n trusted.pin $file
+       $RUNAS $LFS pcc unpin -i $id $file &&
+               error "nonroot user should fail to unpin file"
+       $LFS pcc unpin -i $id $file ||
+               error "root should be able to unpin any file"
+       $RUNAS $LFS pcc pin -i $id $file &&
+               error "nonroot user should fail to pin file"
+
+       do_facet mds1 $LCTL set_param mdt.*.enable_pin_gid=-1
+       $RUNAS $LFS pcc pin -i $id $file ||
+               error "failed to pin $file when enable_pin_gid=-1"
+       $RUNAS $LFS pcc unpin -i $id $file ||
+               error "failed to unpin $file when enable_pin_gid=-1"
+
+       do_facet mds1 $LCTL set_param mdt.*.enable_pin_gid=$RUNAS_GID
+       $RUNAS $LFS pcc pin -i $id $file ||
+               error "failed to pin $file when enable_pin_gid=$RUNAS_GID"
+       $RUNAS $LFS pcc unpin -i $id $file ||
+               error "failed to unpin $file when enable_pin_gid=$RUNAS_GID"
+       $LFS pcc pin -i $id $file ||
+               error "failed to pin $file when enable_pin_gid=$RUNAS_GID"
+       $LFS pcc unpin -i $id $file ||
+               error "failed to unpin $file when enable_pin_gid=$RUNAS_GID"
+}
+run_test 204b "Permission check for the pin/unpin operation"
+
+test_204c() {
        local loopfile="$TMP/$tfile"
        local mntpt="/mnt/pcc.$tdir"
        local hsm_root="$mntpt/$tdir"
@@ -4727,7 +4775,7 @@ test_204b() {
        xattrvalue=$(do_facet $SINGLEAGT getfattr $file -n $xattrname --only-values)
        [[ -z "$xattrvalue" ]] || error "incorrect xattr $xattrname=$xattrvalue"
 }
-run_test 204b "PCC pin/unpin without attach ID specified"
+run_test 204c "PCC pin/unpin without attach ID specified"
 
 complete_test $SECONDS
 check_and_cleanup_lustre
index 0e4f48f..2c4bcbd 100644 (file)
@@ -927,7 +927,7 @@ static struct cYAML *read_pin_xattr_object(const char *path)
        struct cYAML *yaml = NULL;
        char buff[XATTR_SIZE_MAX];
 
-       rc = getxattr(path, XATTR_NAME_PIN, buff, sizeof(buff));
+       rc = getxattr(path, XATTR_LUSTRE_PIN, buff, sizeof(buff));
        if (rc < 0)
                goto out;
 
@@ -1006,7 +1006,7 @@ int llapi_pcc_pin_file(const char *path, __u32 id)
                goto out;
 
 set:
-       rc = setxattr(path, XATTR_NAME_PIN, buff, strlen(buff), 0);
+       rc = setxattr(path, XATTR_LUSTRE_PIN, buff, strlen(buff), 0);
        if (rc < 0)
                rc = -errno;
 out:
@@ -1064,9 +1064,9 @@ int llapi_pcc_unpin_file(const char *path, __u32 id)
                goto out;
 
        if (strlen(buff) == 0)
-               rc = removexattr(path, XATTR_NAME_PIN);
+               rc = removexattr(path, XATTR_LUSTRE_PIN);
        else
-               rc = setxattr(path, XATTR_NAME_PIN, buff, strlen(buff), 0);
+               rc = setxattr(path, XATTR_LUSTRE_PIN, buff, strlen(buff), 0);
 
        if (rc < 0)
                rc = -errno;