Whamcloud - gitweb
LU-16077 tbf: pb_uid/pb_gid ptlrpc_body fields for TBF rules 35/48235/7
authorEtienne AUJAMES <etienne.aujames@cea.fr>
Fri, 12 Aug 2022 19:41:08 +0000 (21:41 +0200)
committerOleg Drokin <green@whamcloud.com>
Tue, 18 Apr 2023 03:21:53 +0000 (03:21 +0000)
The file UID/GID are packed inside bulk IO because the requests are
sent asynchronously (cannot use the current thread UID/GID).

This is an issue for TBF rules if the file/inode UID/GID doesn't
match the process ones (e.g: reading common libraries): we can't limit
the user RPCs doing the IOs in that case.

This patch pack UID/GID for TBF rules inside ptlrpc_body (
pb_padding64_2 -> (pb_uid, pb_gid)) to be independent of quota
interactions: it stores the client process UID/GID instead of the
values of the file attrs.
Moreover, it enables to track requests naturally without UID/GID like
ldlm_flock_enqueue.

This patch saves the process UID/GID inside the ll_inode_info struct.
Then it restores these values when sending a bulk IO from a ptlrpc
thread (like for jobids).

Add sanityn test_77jb to verify.

Fixes: e0cdde1 ("LU-9658 ptlrpc: Add QoS for uid and gid in NRS-TBF")
Test-Parameters: testlist=sanityn env=ONLY=77,ONLY_REPEAT=20
Test-Parameters: serverversion=2.12.9 testlist=sanityn env=ONLY=77
Test-Parameters: clientversion=2.12.9 testlist=sanityn env=ONLY=77
Signed-off-by: Etienne AUJAMES <etienne.aujames@cea.fr>
Change-Id: I61e42267ae568f9a1eb6fe57937a5e96f1824010
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/48235
Reviewed-by: Qian Yingjin <qian@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
16 files changed:
lustre/include/cl_object.h
lustre/include/lustre_net.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/vvp_io.c
lustre/llite/vvp_object.c
lustre/osc/osc_request.c
lustre/ptlrpc/client.c
lustre/ptlrpc/nrs_tbf.c
lustre/ptlrpc/pack_generic.c
lustre/ptlrpc/ptlrpcd.c
lustre/ptlrpc/wiretest.c
lustre/tests/sanityn.sh
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 7284109..c6607cd 100644 (file)
@@ -1966,6 +1966,9 @@ struct cl_req_attr {
        struct obdo     *cra_oa;
        /** Jobid */
        char             cra_jobid[LUSTRE_JOBID_SIZE];
+       /** uid/gid of the process doing an io */
+       u32 cra_uid;
+       u32 cra_gid;
 };
 
 enum cache_stats_item {
index 0c42928..42ee5bf 100644 (file)
@@ -2347,6 +2347,7 @@ __u32 lustre_msg_get_conn_cnt(struct lustre_msg *msg);
 __u32 lustre_msg_get_magic(struct lustre_msg *msg);
 timeout_t lustre_msg_get_timeout(struct lustre_msg *msg);
 timeout_t lustre_msg_get_service_timeout(struct lustre_msg *msg);
+int lustre_msg_get_uid_gid(struct lustre_msg *msg, __u32 *uid, __u32 *gid);
 char *lustre_msg_get_jobid(struct lustre_msg *msg);
 __u32 lustre_msg_get_cksum(struct lustre_msg *msg);
 __u64 lustre_msg_get_mbits(struct lustre_msg *msg);
@@ -2366,6 +2367,7 @@ void ptlrpc_request_set_replen(struct ptlrpc_request *req);
 void lustre_msg_set_timeout(struct lustre_msg *msg, timeout_t timeout);
 void lustre_msg_set_service_timeout(struct lustre_msg *msg,
                                    timeout_t service_timeout);
+void lustre_msg_set_uid_gid(struct lustre_msg *msg, __u32 *uid, __u32 *gid);
 void lustre_msg_set_jobid(struct lustre_msg *msg, char *jobid);
 void lustre_msg_set_cksum(struct lustre_msg *msg, __u32 cksum);
 void lustre_msg_set_mbits(struct lustre_msg *msg, __u64 mbits);
index 82f86ca..e8974b9 100644 (file)
@@ -657,6 +657,7 @@ enum lustre_msg_version {
 /* #define MSG_CONNECT_ASYNC   0x00000040 obsolete since 1.5 */
 #define MSG_CONNECT_NEXT_VER   0x00000080 /* use next version of lustre_msg */
 #define MSG_CONNECT_TRANSNO    0x00000100 /* client sent transno in replay */
+#define MSG_PACK_UID_GID       0x00000200 /* thread UID/GID in ptlrpc_body */
 
 /* number of previous object versions in pb_pre_versions[] */
 #define PTLRPC_NUM_VERSIONS     4
@@ -686,7 +687,8 @@ struct ptlrpc_body_v3 {
        /* padding for future needs - fix lustre_swab_ptlrpc_body() also */
        __u64 pb_padding64_0;
        __u64 pb_padding64_1;
-       __u64 pb_padding64_2;
+       __u32 pb_uid;           /* req: process uid, use by tbf rules */
+       __u32 pb_gid;           /* req: process gid, use by tbf rules */
        char  pb_jobid[LUSTRE_JOBID_SIZE]; /* req: ASCII jobid from env + NUL */
 };
 #define ptlrpc_body     ptlrpc_body_v3
index bb36cee..c493fb5 100644 (file)
@@ -221,13 +221,16 @@ struct ll_inode_info {
 
                        /*
                         * Whenever a process try to read/write the file, the
-                        * jobid of the process will be saved here, and it'll
-                        * be packed into the write PRC when flush later.
+                        * jobid, uid and gid of the process will be saved here,
+                        * and it'll be packed into write RPC when flush later.
                         *
-                        * So the read/write statistics for jobid will not be
-                        * accurate if the file is shared by different jobs.
+                        * So the read/write statistics or TBF rules for jobid,
+                        * uid or gid will not be accurate if the file is shared
+                        * by different jobs.
                         */
                        char                    lli_jobid[LUSTRE_JOBID_SIZE];
+                       __u32                   lli_uid;
+                       __u32                   lli_gid;
 
                        struct mutex             lli_pcc_lock;
                        enum lu_pcc_state_flags  lli_pcc_state;
index f20efc4..4ed4fec 100644 (file)
@@ -1263,9 +1263,11 @@ void ll_lli_init(struct ll_inode_info *lli)
                mutex_init(&lli->lli_group_mutex);
                lli->lli_group_users = 0;
                lli->lli_group_gid = 0;
+               memset(lli->lli_jobid, 0, sizeof(lli->lli_jobid));
+               lli->lli_uid = (__u32) -1;
+               lli->lli_gid = (__u32) -1;
        }
        mutex_init(&lli->lli_layout_mutex);
-       memset(lli->lli_jobid, 0, sizeof(lli->lli_jobid));
        /* ll_cl_context initialize */
        INIT_LIST_HEAD(&lli->lli_lccs);
        seqlock_init(&lli->lli_page_inv_lock);
index f3f803b..a8c85da 100644 (file)
@@ -1827,13 +1827,15 @@ int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
                else
                        vio->vui_tot_count = count;
 
-               /* for read/write, we store the jobid in the inode, and
-                * it'll be fetched by osc when building RPC.
+               /* for read/write, we store the process jobid/gid/uid in the
+                * inode, and it'll be fetched by osc when building RPC.
                 *
                 * it's not accurate if the file is shared by different
-                * jobs.
+                * jobs/user/group.
                 */
                lustre_get_jobid(lli->lli_jobid, sizeof(lli->lli_jobid));
+               lli->lli_uid = from_kuid(&init_user_ns, current_uid());
+               lli->lli_gid = from_kgid(&init_user_ns, current_gid());
        } else if (io->ci_type == CIT_SETATTR) {
                if (!cl_io_is_trunc(io))
                        io->ci_lockreq = CILR_MANDATORY;
index 650df1b..3e089df 100644 (file)
@@ -205,11 +205,13 @@ static void vvp_req_attr_set(const struct lu_env *env, struct cl_object *obj,
 {
        struct inode *inode;
        struct obdo  *oa;
+       struct ll_inode_info *lli;
        u64 valid_flags = OBD_MD_FLTYPE | OBD_MD_FLUID | OBD_MD_FLGID |
                          OBD_MD_FLPROJID;
 
        oa = attr->cra_oa;
        inode = vvp_object_inode(obj);
+       lli = ll_i2info(inode);
 
        if (attr->cra_type == CRT_WRITE) {
                valid_flags |= OBD_MD_FLMTIME | OBD_MD_FLCTIME;
@@ -221,8 +223,11 @@ static void vvp_req_attr_set(const struct lu_env *env, struct cl_object *obj,
        obdo_set_parent_fid(oa, &ll_i2info(inode)->lli_fid);
        if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_INVALID_PFID))
                oa->o_parent_oid++;
-       memcpy(attr->cra_jobid, ll_i2info(inode)->lli_jobid,
-              sizeof(attr->cra_jobid));
+
+       attr->cra_uid = lli->lli_uid;
+       attr->cra_gid = lli->lli_gid;
+
+       memcpy(attr->cra_jobid, &lli->lli_jobid, sizeof(attr->cra_jobid));
 }
 
 static const struct cl_object_operations vvp_ops = {
index 1a8cf65..bc3be85 100644 (file)
@@ -2777,6 +2777,8 @@ int osc_build_rpc(const struct lu_env *env, struct client_obd *cli,
        crattr->cra_oa = &body->oa;
        crattr->cra_flags = OBD_MD_FLMTIME | OBD_MD_FLCTIME | OBD_MD_FLATIME;
        cl_req_attr_set(env, osc2cl(obj), crattr);
+       lustre_msg_set_uid_gid(req->rq_reqmsg, &crattr->cra_uid,
+                              &crattr->cra_gid);
        lustre_msg_set_jobid(req->rq_reqmsg, crattr->cra_jobid);
 
        aa = ptlrpc_req_async_args(aa, req);
index 3f498a2..deac037 100644 (file)
@@ -1170,8 +1170,10 @@ void ptlrpc_set_add_req(struct ptlrpc_request_set *set,
        atomic_inc(&set->set_remaining);
        req->rq_queued_time = ktime_get_seconds();
 
-       if (req->rq_reqmsg)
+       if (req->rq_reqmsg) {
                lustre_msg_set_jobid(req->rq_reqmsg, NULL);
+               lustre_msg_set_uid_gid(req->rq_reqmsg, NULL, NULL);
+       }
 
        if (set->set_producer)
                /*
index 6f1c351..023931a 100644 (file)
@@ -1602,6 +1602,13 @@ static int nrs_tbf_id_cli_set(struct ptlrpc_request *req, struct tbf_id *id,
        memset(id, 0, sizeof(struct tbf_id));
        id->ti_type = ti_type;
 
+       rc = lustre_msg_get_uid_gid(req->rq_reqmsg, &id->ti_uid, &id->ti_gid);
+       if (!rc && id->ti_uid != (u32) -1 && id->ti_gid != (u32) -1)
+               return 0;
+
+       /* client req doesn't have uid/gid pack in ptlrpc_body
+        * --> fallback to the old method
+        */
        if (fmt == NULL)
                return -EINVAL;
        req_capsule_init(&req->rq_pill, req, RCL_SERVER);
index b4540a1..8c3f839 100644 (file)
@@ -1308,6 +1308,37 @@ timeout_t lustre_msg_get_service_timeout(struct lustre_msg *msg)
        }
 }
 
+int lustre_msg_get_uid_gid(struct lustre_msg *msg, __u32 *uid, __u32 *gid)
+{
+       switch (msg->lm_magic) {
+       case LUSTRE_MSG_MAGIC_V2: {
+               struct ptlrpc_body *pb;
+
+               /* the old pltrpc_body_v2 is smaller; doesn't include uid/gid */
+               if (msg->lm_buflens[MSG_PTLRPC_BODY_OFF] <
+                   sizeof(struct ptlrpc_body))
+                       return -EOPNOTSUPP;
+
+               pb = lustre_msg_buf_v2(msg, MSG_PTLRPC_BODY_OFF,
+                                         sizeof(struct ptlrpc_body));
+
+               if (!pb || !(pb->pb_flags & MSG_PACK_UID_GID))
+                       return -EOPNOTSUPP;
+
+               if (uid)
+                       *uid = pb->pb_uid;
+               if (gid)
+                       *gid = pb->pb_gid;
+
+               return 0;
+       }
+       default:
+               CERROR("incorrect message magic: %08x\n", msg->lm_magic);
+               return -EOPNOTSUPP;
+       }
+}
+EXPORT_SYMBOL(lustre_msg_get_uid_gid);
+
 char *lustre_msg_get_jobid(struct lustre_msg *msg)
 {
        switch (msg->lm_magic) {
@@ -1576,6 +1607,40 @@ void lustre_msg_set_service_timeout(struct lustre_msg *msg,
        }
 }
 
+void lustre_msg_set_uid_gid(struct lustre_msg *msg, __u32 *uid, __u32 *gid)
+{
+       switch (msg->lm_magic) {
+       case LUSTRE_MSG_MAGIC_V2: {
+               __u32 opc = lustre_msg_get_opc(msg);
+               struct ptlrpc_body *pb;
+
+               /* Don't set uid/gid for ldlm ast RPCs */
+               if (!opc || opc == LDLM_BL_CALLBACK ||
+                   opc == LDLM_CP_CALLBACK || opc == LDLM_GL_CALLBACK)
+                       return;
+
+               pb = lustre_msg_buf_v2(msg, MSG_PTLRPC_BODY_OFF,
+                                      sizeof(struct ptlrpc_body));
+               LASSERTF(pb, "invalid msg %p: no ptlrpc body!\n", msg);
+
+               if (uid && gid) {
+                       pb->pb_uid = *uid;
+                       pb->pb_gid = *gid;
+                       pb->pb_flags |= MSG_PACK_UID_GID;
+               } else if (!(pb->pb_flags & MSG_PACK_UID_GID)) {
+                       pb->pb_uid = from_kuid(&init_user_ns, current_uid());
+                       pb->pb_gid = from_kgid(&init_user_ns, current_gid());
+                       pb->pb_flags |= MSG_PACK_UID_GID;
+               }
+
+               return;
+       }
+       default:
+               LASSERTF(0, "incorrect message magic: %08x\n", msg->lm_magic);
+       }
+}
+EXPORT_SYMBOL(lustre_msg_set_uid_gid);
+
 void lustre_msg_set_jobid(struct lustre_msg *msg, char *jobid)
 {
        switch (msg->lm_magic) {
@@ -1733,7 +1798,8 @@ void lustre_swab_ptlrpc_body(struct ptlrpc_body *body)
        __swab64s(&body->pb_mbits);
        BUILD_BUG_ON(offsetof(typeof(*body), pb_padding64_0) == 0);
        BUILD_BUG_ON(offsetof(typeof(*body), pb_padding64_1) == 0);
-       BUILD_BUG_ON(offsetof(typeof(*body), pb_padding64_2) == 0);
+       __swab32s(&body->pb_uid);
+       __swab32s(&body->pb_gid);
        /*
         * While we need to maintain compatibility between
         * clients and servers without ptlrpc_body_v2 (< 2.3)
@@ -2779,6 +2845,12 @@ void _debug_req(struct ptlrpc_request *req,
        va_list args;
        int rep_flags = -1;
        int rep_status = -1;
+       __u64 req_transno = 0;
+       int req_opc = -1;
+       __u32 req_flags =  (__u32) -1;
+       __u32 req_uid = (__u32) -1;
+       __u32 req_gid = (__u32) -1;
+       char *req_jobid = NULL;
 
        spin_lock(&req->rq_early_free_lock);
        if (req->rq_repmsg)
@@ -2800,15 +2872,22 @@ void _debug_req(struct ptlrpc_request *req,
        else if (req->rq_export && req->rq_export->exp_connection)
                nid = &req->rq_export->exp_connection->c_peer.nid;
 
+       if (req_ok) {
+               req_transno = lustre_msg_get_transno(req->rq_reqmsg);
+               req_opc = lustre_msg_get_opc(req->rq_reqmsg);
+               req_jobid = lustre_msg_get_jobid(req->rq_reqmsg);
+               lustre_msg_get_uid_gid(req->rq_reqmsg, &req_uid, &req_gid);
+               req_flags = lustre_msg_get_flags(req->rq_reqmsg);
+       }
+
        va_start(args, fmt);
        vaf.fmt = fmt;
        vaf.va = &args;
        libcfs_debug_msg(msgdata,
-                        "%pV req@%p x%llu/t%lld(%lld) o%d->%s@%s:%d/%d lens %d/%d e %d to %lld dl %lld ref %d fl " REQ_FLAGS_FMT "/%x/%x rc %d/%d job:'%s'\n",
+                        "%pV req@%p x%llu/t%lld(%llu) o%d->%s@%s:%d/%d lens %d/%d e %d to %lld dl %lld ref %d fl " REQ_FLAGS_FMT "/%x/%x rc %d/%d uid:%u gid:%u job:'%s'\n",
                         &vaf,
-                        req, req->rq_xid, req->rq_transno,
-                        req_ok ? lustre_msg_get_transno(req->rq_reqmsg) : 0,
-                        req_ok ? lustre_msg_get_opc(req->rq_reqmsg) : -1,
+                        req, req->rq_xid, req->rq_transno, req_transno,
+                        req_opc,
                         req->rq_import ?
                         req->rq_import->imp_obd->obd_name :
                         req->rq_export ?
@@ -2820,11 +2899,9 @@ void _debug_req(struct ptlrpc_request *req,
                         req->rq_early_count, (s64)req->rq_timedout,
                         (s64)req->rq_deadline,
                         atomic_read(&req->rq_refcount),
-                        DEBUG_REQ_FLAGS(req),
-                        req_ok ? lustre_msg_get_flags(req->rq_reqmsg) : -1,
-                        rep_flags, req->rq_status, rep_status,
-                        req_ok ? lustre_msg_get_jobid(req->rq_reqmsg) ?: ""
-                               : "");
+                        DEBUG_REQ_FLAGS(req), req_flags, rep_flags,
+                        req->rq_status, rep_status,
+                        req_uid, req_gid, req_jobid ?: "");
        va_end(args);
 }
 EXPORT_SYMBOL(_debug_req);
index 9d29cc7..35f7e08 100644 (file)
@@ -266,8 +266,10 @@ void ptlrpcd_add_req(struct ptlrpc_request *req)
 {
        struct ptlrpcd_ctl *pc;
 
-       if (req->rq_reqmsg)
+       if (req->rq_reqmsg) {
                lustre_msg_set_jobid(req->rq_reqmsg, NULL);
+               lustre_msg_set_uid_gid(req->rq_reqmsg, NULL, NULL);
+       }
 
        spin_lock(&req->rq_lock);
        if (req->rq_invalid_rqset) {
index 0a94358..f476931 100644 (file)
@@ -932,10 +932,14 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct ptlrpc_body_v3, pb_padding64_1));
        LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_1) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_1));
-       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_padding64_2) == 144, "found %lld\n",
-                (long long)(int)offsetof(struct ptlrpc_body_v3, pb_padding64_2));
-       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2));
+       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_uid) == 144, "found %lld\n",
+                (long long)(int)offsetof(struct ptlrpc_body_v3, pb_uid));
+       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid));
+       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_gid) == 148, "found %lld\n",
+                (long long)(int)offsetof(struct ptlrpc_body_v3, pb_gid));
+       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid));
        BUILD_BUG_ON(LUSTRE_JOBID_SIZE != 32);
        LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_jobid) == 152, "found %lld\n",
                 (long long)(int)offsetof(struct ptlrpc_body_v3, pb_jobid));
@@ -1029,10 +1033,12 @@ void lustre_assert_wire_constants(void)
                 (int)offsetof(struct ptlrpc_body_v3, pb_padding64_1), (int)offsetof(struct ptlrpc_body_v2, pb_padding64_1));
        LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_1) == (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_1), "%d != %d\n",
                 (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_1), (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_1));
-       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_padding64_2) == (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2), "%d != %d\n",
-                (int)offsetof(struct ptlrpc_body_v3, pb_padding64_2), (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2));
-       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2) == (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2), "%d != %d\n",
-                (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2), (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2));
+       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_uid) == (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2), "%d != %d\n",
+                (int)offsetof(struct ptlrpc_body_v3, pb_uid), (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2));
+       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid) + (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid) ==
+                (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2), "%d != %d\n",
+                (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid) + (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid),
+                (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2));
        LASSERTF(MSG_PTLRPC_BODY_OFF == 0, "found %lld\n",
                 (long long)MSG_PTLRPC_BODY_OFF);
        LASSERTF(REQ_REC_OFF == 1, "found %lld\n",
index a1f2d03..86664a0 100755 (executable)
@@ -3848,11 +3848,21 @@ nrs_write_read() {
        local n=16
        local dir=$DIR/$tdir
        local myRUNAS="$1"
+       local create_as="$2"
 
        mkdir $dir || error "mkdir $dir failed"
        $LFS setstripe -c $OSTCOUNT $dir || error "setstripe to $dir failed"
        chmod 777 $dir
 
+       if [[ -n "$create_as" ]]; then
+               do_nodes $CLIENTS $create_as "touch $dir/nrs_r_\$HOSTNAME;" ||
+                       error "touch failed for $dir/nrs_r_*"
+               do_nodes $CLIENTS $create_as touch "$dir/nrs_w_\$HOSTNAME" ||
+                       error "touch failed for $dir/nrs_w_*"
+               do_nodes $CLIENTS $create_as "chmod 777 $dir/nrs_*_\$HOSTNAME;" ||
+                       error "chmod failed for $dir/nrs_*"
+       fi
+
        do_nodes $CLIENTS $myRUNAS \
                dd if=/dev/zero of="$dir/nrs_r_\$HOSTNAME" bs=1M count=$n ||
                error "dd at 0 on client failed (1)"
@@ -4018,6 +4028,7 @@ tbf_verify() {
        local dir=$DIR/$tdir
        local client1=${CLIENT1:-$(hostname)}
        local myRUNAS="$3"
+       local create_as="$4"
 
        local np=$(check_cpt_number ost1)
        [ $np -gt 0 ] || error "CPU partitions should not be $np."
@@ -4027,6 +4038,11 @@ tbf_verify() {
        $LFS setstripe -c 1 -i 0 $dir || error "setstripe to $dir failed"
        chmod 777 $dir
 
+       if [[ -n "$create_as" ]]; then
+               $create_as touch $dir/tbf
+               chmod 777 $dir/tbf
+       fi
+
        trap cleanup_tbf_verify EXIT
        echo "Limited write rate: $1, read rate: $2"
        echo "Verify the write rate is under TBF control"
@@ -4343,6 +4359,8 @@ test_id() {
        local idstr="${1}id"
        local policy="${idstr}={$2}"
        local rate="rate=$3"
+       local runas_args="$4"
+       local createas_args="${5:-$runas_args}"
 
        do_nodes $(comma_list $(osts_nodes)) \
                lctl set_param jobid_var=procname_uid \
@@ -4350,8 +4368,8 @@ test_id() {
                        ost.OSS.ost_io.nrs_tbf_rule="start\ ost_${idstr}\ ${policy}\ ${rate}"
        [ $? -ne 0 ] && error "failed to set tbf ${idstr} policy"
 
-       nrs_write_read "runas $4"
-       tbf_verify $3 $3 "runas $4"
+       nrs_write_read "runas $runas_args" "runas $createas_args"
+       tbf_verify $3 $3 "runas $runas_args" "runas $createas_args"
 
        do_nodes $(comma_list $(osts_nodes)) \
                lctl set_param ost.OSS.ost_io.nrs_tbf_rule="stop\ ost_${idstr}" \
@@ -4373,6 +4391,15 @@ test_77ja(){
 }
 run_test 77ja "check TBF-UID/GID NRS policy"
 
+test_77jb() { # LU-16077
+       (( "$OST1_VERSION" >= $(version_code 2.15.51) )) ||
+               skip "Need OST version at least 2.15.51"
+
+       test_id "u" "500" "5" "-u 500" "-u 0 -g 500"
+       test_id "g" "500" "5" "-u 500 -g 500" "-u 500 -g 0"
+}
+run_test 77jb "check TBF-UID/GID NRS policy on files that don't belong to us"
+
 cleanup_77k()
 {
        local rule_lists=$1
index edb6ffb..d29067d 100644 (file)
@@ -460,7 +460,8 @@ check_ptlrpc_body(void)
        CHECK_MEMBER(ptlrpc_body, pb_mbits);
        CHECK_MEMBER(ptlrpc_body, pb_padding64_0);
        CHECK_MEMBER(ptlrpc_body, pb_padding64_1);
-       CHECK_MEMBER(ptlrpc_body, pb_padding64_2);
+       CHECK_MEMBER(ptlrpc_body, pb_uid);
+       CHECK_MEMBER(ptlrpc_body, pb_gid);
        CHECK_CVALUE(LUSTRE_JOBID_SIZE);
        CHECK_MEMBER(ptlrpc_body, pb_jobid);
 
@@ -486,7 +487,11 @@ check_ptlrpc_body(void)
        CHECK_MEMBER_SAME(ptlrpc_body_v3, ptlrpc_body_v2, pb_mbits);
        CHECK_MEMBER_SAME(ptlrpc_body_v3, ptlrpc_body_v2, pb_padding64_0);
        CHECK_MEMBER_SAME(ptlrpc_body_v3, ptlrpc_body_v2, pb_padding64_1);
-       CHECK_MEMBER_SAME(ptlrpc_body_v3, ptlrpc_body_v2, pb_padding64_2);
+       CHECK_VALUE_SAME((int)offsetof(struct ptlrpc_body_v3, pb_uid),
+                        (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2));
+       CHECK_VALUE_SAME((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid +
+                                    (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid),
+                        (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2));
 
        CHECK_VALUE(MSG_PTLRPC_BODY_OFF);
        CHECK_VALUE(REQ_REC_OFF);
index 8c27bf4..31bda08 100644 (file)
@@ -958,10 +958,14 @@ void lustre_assert_wire_constants(void)
                 (long long)(int)offsetof(struct ptlrpc_body_v3, pb_padding64_1));
        LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_1) == 8, "found %lld\n",
                 (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_1));
-       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_padding64_2) == 144, "found %lld\n",
-                (long long)(int)offsetof(struct ptlrpc_body_v3, pb_padding64_2));
-       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2) == 8, "found %lld\n",
-                (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2));
+       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_uid) == 144, "found %lld\n",
+                (long long)(int)offsetof(struct ptlrpc_body_v3, pb_uid));
+       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid));
+       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_gid) == 148, "found %lld\n",
+                (long long)(int)offsetof(struct ptlrpc_body_v3, pb_gid));
+       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid) == 4, "found %lld\n",
+                (long long)(int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid));
        BUILD_BUG_ON(LUSTRE_JOBID_SIZE != 32);
        LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_jobid) == 152, "found %lld\n",
                 (long long)(int)offsetof(struct ptlrpc_body_v3, pb_jobid));
@@ -1055,10 +1059,12 @@ void lustre_assert_wire_constants(void)
                 (int)offsetof(struct ptlrpc_body_v3, pb_padding64_1), (int)offsetof(struct ptlrpc_body_v2, pb_padding64_1));
        LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_1) == (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_1), "%d != %d\n",
                 (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_1), (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_1));
-       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_padding64_2) == (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2), "%d != %d\n",
-                (int)offsetof(struct ptlrpc_body_v3, pb_padding64_2), (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2));
-       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2) == (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2), "%d != %d\n",
-                (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_padding64_2), (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2));
+       LASSERTF((int)offsetof(struct ptlrpc_body_v3, pb_uid) == (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2), "%d != %d\n",
+                (int)offsetof(struct ptlrpc_body_v3, pb_uid), (int)offsetof(struct ptlrpc_body_v2, pb_padding64_2));
+       LASSERTF((int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid) + (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid) ==
+                (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2), "%d != %d\n",
+                (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_uid) + (int)sizeof(((struct ptlrpc_body_v3 *)0)->pb_gid),
+                (int)sizeof(((struct ptlrpc_body_v2 *)0)->pb_padding64_2));
        LASSERTF(MSG_PTLRPC_BODY_OFF == 0, "found %lld\n",
                 (long long)MSG_PTLRPC_BODY_OFF);
        LASSERTF(REQ_REC_OFF == 1, "found %lld\n",