@@ -1974,6 +1974,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 {
@@ -2088,6 +2088,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);
@@ -2106,6 +2107,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);
@@ -230,13 +230,17 @@ 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;
@@ -1215,9 +1215,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);
@@ -1741,13 +1741,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;
@@ -199,11 +199,13 @@ static void vvp_req_attr_set(const struct lu_env *env, struct cl_object *obj,
{
u64 valid_flags = OBD_MD_FLTYPE | OBD_MD_FLUID | OBD_MD_FLGID |
OBD_MD_FLPROJID;
+ struct ll_inode_info *lli;
struct inode *inode;
struct obdo *oa;
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;
@@ -215,8 +217,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 = {
@@ -2797,6 +2797,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);
@@ -1159,8 +1159,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)
/*
@@ -1182,6 +1182,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) {
@@ -1443,6 +1474,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) {
@@ -1592,7 +1657,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)
* do not swab any fields beyond pb_jobid, as we are
@@ -2473,8 +2539,14 @@ void _debug_req(struct ptlrpc_request *req,
struct lnet_nid *nid = NULL;
int rep_flags = -1;
int rep_status = -1;
- va_list args;
+ 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;
struct va_format vaf;
+ va_list args;
spin_lock(&req->rq_early_free_lock);
if (req->rq_repmsg)
@@ -2496,15 +2568,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 ?
@@ -2516,11 +2595,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);
@@ -224,8 +224,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) {
@@ -772,10 +772,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));
@@ -869,10 +873,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",
@@ -593,6 +593,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
@@ -622,7 +623,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 */
};