From 0544c108c12c87a43562b4ef31120448bf0018c8 Mon Sep 17 00:00:00 2001 From: Etienne AUJAMES Date: Fri, 12 Aug 2022 21:41:08 +0200 Subject: [PATCH] LU-16077 tbf: pb_uid/pb_gid ptlrpc_body fields for TBF rules 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 Change-Id: I61e42267ae568f9a1eb6fe57937a5e96f1824010 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/48235 Reviewed-by: Qian Yingjin Reviewed-by: Oleg Drokin Reviewed-by: Andreas Dilger Tested-by: jenkins Tested-by: Maloo --- lustre/include/cl_object.h | 3 + lustre/include/lustre_net.h | 2 + lustre/include/uapi/linux/lustre/lustre_idl.h | 4 +- lustre/llite/llite_internal.h | 11 +-- lustre/llite/llite_lib.c | 4 +- lustre/llite/vvp_io.c | 8 ++- lustre/llite/vvp_object.c | 9 ++- lustre/osc/osc_request.c | 2 + lustre/ptlrpc/client.c | 4 +- lustre/ptlrpc/nrs_tbf.c | 7 ++ lustre/ptlrpc/pack_generic.c | 97 ++++++++++++++++++++++++--- lustre/ptlrpc/ptlrpcd.c | 4 +- lustre/ptlrpc/wiretest.c | 22 +++--- lustre/tests/sanityn.sh | 31 ++++++++- lustre/utils/wirecheck.c | 9 ++- lustre/utils/wiretest.c | 22 +++--- 16 files changed, 196 insertions(+), 43 deletions(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 7284109..c6607cd 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -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 { diff --git a/lustre/include/lustre_net.h b/lustre/include/lustre_net.h index 0c42928..42ee5bf 100644 --- a/lustre/include/lustre_net.h +++ b/lustre/include/lustre_net.h @@ -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); diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 82f86ca..e8974b9 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -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 diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index bb36cee..c493fb5 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -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; diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index f20efc4..4ed4fec 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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); diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index f3f803bd..a8c85da 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -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; diff --git a/lustre/llite/vvp_object.c b/lustre/llite/vvp_object.c index 650df1b..3e089df 100644 --- a/lustre/llite/vvp_object.c +++ b/lustre/llite/vvp_object.c @@ -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 = { diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 1a8cf65..bc3be85 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -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); diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index 3f498a2..deac037 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -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) /* diff --git a/lustre/ptlrpc/nrs_tbf.c b/lustre/ptlrpc/nrs_tbf.c index 6f1c351..023931a 100644 --- a/lustre/ptlrpc/nrs_tbf.c +++ b/lustre/ptlrpc/nrs_tbf.c @@ -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); diff --git a/lustre/ptlrpc/pack_generic.c b/lustre/ptlrpc/pack_generic.c index b4540a1..8c3f839 100644 --- a/lustre/ptlrpc/pack_generic.c +++ b/lustre/ptlrpc/pack_generic.c @@ -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); diff --git a/lustre/ptlrpc/ptlrpcd.c b/lustre/ptlrpc/ptlrpcd.c index 9d29cc7..35f7e08 100644 --- a/lustre/ptlrpc/ptlrpcd.c +++ b/lustre/ptlrpc/ptlrpcd.c @@ -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) { diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index 0a94358..f476931 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -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", diff --git a/lustre/tests/sanityn.sh b/lustre/tests/sanityn.sh index a1f2d03..86664a0 100755 --- a/lustre/tests/sanityn.sh +++ b/lustre/tests/sanityn.sh @@ -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 diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index edb6ffb..d29067d 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -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); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 8c27bf4..31bda08 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -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", -- 1.8.3.1